diff --git a/CMakeLists.txt b/CMakeLists.txt index ef9b83b899..4264d4a640 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,23 +27,26 @@ set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake ${CMAKE_MODULE_PATH}) set(ZIG_VERSION_MAJOR 0) set(ZIG_VERSION_MINOR 6) set(ZIG_VERSION_PATCH 0) -set(ZIG_VERSION "${ZIG_VERSION_MAJOR}.${ZIG_VERSION_MINOR}.${ZIG_VERSION_PATCH}") +set(ZIG_VERSION "" CACHE STRING "Override Zig version string. Default is to find out with git.") -find_program(GIT_EXE NAMES git) -if(GIT_EXE) - execute_process( - COMMAND ${GIT_EXE} -C ${CMAKE_SOURCE_DIR} name-rev HEAD --tags --name-only --no-undefined --always - RESULT_VARIABLE EXIT_STATUS - OUTPUT_VARIABLE ZIG_GIT_REV - OUTPUT_STRIP_TRAILING_WHITESPACE - ERROR_QUIET) - if(EXIT_STATUS EQUAL "0") - if(ZIG_GIT_REV MATCHES "\\^0$") - if(NOT("${ZIG_GIT_REV}" STREQUAL "${ZIG_VERSION}^0")) - message("WARNING: Tag does not match configured Zig version") +if("${ZIG_VERSION}" STREQUAL "") + set(ZIG_VERSION "${ZIG_VERSION_MAJOR}.${ZIG_VERSION_MINOR}.${ZIG_VERSION_PATCH}") + find_program(GIT_EXE NAMES git) + if(GIT_EXE) + execute_process( + COMMAND ${GIT_EXE} -C ${CMAKE_SOURCE_DIR} name-rev HEAD --tags --name-only --no-undefined --always + RESULT_VARIABLE EXIT_STATUS + OUTPUT_VARIABLE ZIG_GIT_REV + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_QUIET) + if(EXIT_STATUS EQUAL "0") + if(ZIG_GIT_REV MATCHES "\\^0$") + if(NOT("${ZIG_GIT_REV}" STREQUAL "${ZIG_VERSION}^0")) + message("WARNING: Tag does not match configured Zig version") + endif() + else() + set(ZIG_VERSION "${ZIG_VERSION}+${ZIG_GIT_REV}") endif() - else() - set(ZIG_VERSION "${ZIG_VERSION}+${ZIG_GIT_REV}") endif() endif() endif() @@ -63,6 +66,9 @@ endif() if(ZIG_STATIC) set(ZIG_STATIC_LLVM "on") + set(ZIG_LINK_MODE "Static") +else() + set(ZIG_LINK_MODE "Dynamic") endif() string(REGEX REPLACE "\\\\" "\\\\\\\\" ZIG_LIBC_LIB_DIR_ESCAPED "${ZIG_LIBC_LIB_DIR}") @@ -74,6 +80,7 @@ option(ZIG_TEST_COVERAGE "Build Zig with test coverage instrumentation" OFF) set(ZIG_TARGET_TRIPLE "native" CACHE STRING "arch-os-abi to output binaries for") set(ZIG_TARGET_MCPU "baseline" CACHE STRING "-mcpu parameter to output binaries for") set(ZIG_EXECUTABLE "" CACHE STRING "(when cross compiling) path to already-built zig binary") +set(ZIG_PREFER_LLVM_CONFIG off CACHE BOOL "(when cross compiling) use llvm-config to find target llvm dependencies if needed") find_package(llvm) find_package(clang) @@ -257,7 +264,6 @@ target_include_directories(embedded_softfloat PUBLIC ) include_directories("${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/include") set(SOFTFLOAT_LIBRARIES embedded_softfloat) -include_directories("${CMAKE_SOURCE_DIR}/deps/dbg-macro") find_package(Threads) @@ -487,7 +493,7 @@ if("${ZIG_TARGET_TRIPLE}" STREQUAL "native") endif() else() add_custom_target(zig_build_zig1 ALL - COMMAND "${ZIG_EXECUTABLE}" ${BUILD_ZIG1_ARGS} + COMMAND "${ZIG_EXECUTABLE}" "build-obj" ${BUILD_ZIG1_ARGS} BYPRODUCTS "${ZIG1_OBJECT}" COMMENT STATUS "Building self-hosted component ${ZIG1_OBJECT}" WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" diff --git a/README.md b/README.md index 80ebd8955c..c416893d32 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,6 @@ This step must be repeated when you make changes to any of the C++ source code. * cmake >= 3.15.3 * Microsoft Visual Studio. Supported versions: - - 2015 (version 14) - 2017 (version 15.8) - 2019 (version 16) * LLVM, Clang, LLD development libraries == 11.x diff --git a/ci/azure/pipelines.yml b/ci/azure/pipelines.yml index 7cd1d596b4..5a6d34d6cc 100644 --- a/ci/azure/pipelines.yml +++ b/ci/azure/pipelines.yml @@ -28,20 +28,10 @@ jobs: - job: BuildWindows pool: vmImage: 'windows-2019' - strategy: - matrix: - mingw64: - CHERE_INVOKING: yes - MSYSTEM: MINGW64 - SCRIPT: '%CD:~0,2%\msys64\usr\bin\bash -lc "bash ci/azure/windows_mingw_script"' - msvc: - SCRIPT: ci/azure/windows_msvc_script.bat - timeoutInMinutes: 360 - steps: - powershell: | - (New-Object Net.WebClient).DownloadFile("https://github.com/msys2/msys2-installer/releases/download/2020-07-20/msys2-base-x86_64-20200720.sfx.exe", "sfx.exe") + (New-Object Net.WebClient).DownloadFile("https://github.com/msys2/msys2-installer/releases/download/2020-09-03/msys2-base-x86_64-20200903.sfx.exe", "sfx.exe") .\sfx.exe -y -o\ del sfx.exe displayName: Download/Extract/Install MSYS2 @@ -57,7 +47,7 @@ jobs: - task: DownloadSecureFile@1 inputs: secureFile: s3cfg - - script: $(SCRIPT) + - script: ci/azure/windows_msvc_script.bat name: main displayName: 'Build and test' - job: OnMasterSuccess diff --git a/ci/azure/windows_mingw_script b/ci/azure/windows_mingw_script deleted file mode 100644 index 900baebee3..0000000000 --- a/ci/azure/windows_mingw_script +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/sh - -set -x -set -e - -pacman --noconfirm --needed -S git base-devel mingw-w64-x86_64-toolchain mingw-w64-x86_64-cmake mingw-w64-x86_64-clang mingw-w64-x86_64-lld mingw-w64-x86_64-llvm - -git config core.abbrev 9 - -# Git is wrong for autocrlf being enabled by default on Windows. -# git is mangling files on Windows by default. -# This is the second bug I've tracked down to being caused by autocrlf. -git config core.autocrlf false -# Too late; the files are already mangled. -git checkout . - -ZIGBUILDDIR="$(pwd)/build" -PREFIX="$ZIGBUILDDIR/dist" -CMAKEFLAGS="-DCMAKE_COLOR_MAKEFILE=OFF -DCMAKE_INSTALL_PREFIX=$PREFIX -DZIG_STATIC=ON" - -mkdir $ZIGBUILDDIR -cd $ZIGBUILDDIR - -cmake .. -G 'MSYS Makefiles' -DCMAKE_BUILD_TYPE=RelWithDebInfo $CMAKEFLAGS -DCMAKE_EXE_LINKER_FLAGS='-fuse-ld=lld -Wl,/debug,/pdb:zig.pdb' - -make -j$(nproc) install - -./zig build test-behavior -Dskip-non-native -Dskip-release diff --git a/ci/azure/windows_msvc_install b/ci/azure/windows_msvc_install index 5ee3164682..f2f3dcdfa5 100644 --- a/ci/azure/windows_msvc_install +++ b/ci/azure/windows_msvc_install @@ -4,12 +4,7 @@ set -x set -e pacman -Su --needed --noconfirm - -# Uncomment when https://github.com/msys2/MSYS2-packages/issues/2050 is fixed -#pacman -S --needed --noconfirm wget p7zip python3-pip tar xz -pacman -S --needed --noconfirm wget p7zip tar xz -pacman -U --noconfirm http://repo.msys2.org/mingw/x86_64/mingw-w64-x86_64-python-3.8.4-1-any.pkg.tar.zst -pacman -U --noconfirm http://repo.msys2.org/mingw/x86_64/mingw-w64-x86_64-python-pip-20.0.2-1-any.pkg.tar.xz +pacman -S --needed --noconfirm wget p7zip python3-pip tar xz pip install s3cmd wget -nv "https://ziglang.org/deps/llvm%2bclang%2blld-10.0.0-x86_64-windows-msvc-release-mt.tar.xz" diff --git a/cmake/Findllvm.cmake b/cmake/Findllvm.cmake index 9a2342b0f1..d9b5189b49 100644 --- a/cmake/Findllvm.cmake +++ b/cmake/Findllvm.cmake @@ -32,7 +32,7 @@ if(ZIG_PREFER_CLANG_CPP_DYLIB) /usr/local/llvm11/lib /usr/local/llvm110/lib ) -elseif("${ZIG_TARGET_TRIPLE}" STREQUAL "native") +elseif(("${ZIG_TARGET_TRIPLE}" STREQUAL "native") OR ZIG_PREFER_LLVM_CONFIG) find_program(LLVM_CONFIG_EXE NAMES llvm-config-11 llvm-config-11.0 llvm-config110 llvm-config11 llvm-config PATHS @@ -55,13 +55,13 @@ elseif("${ZIG_TARGET_TRIPLE}" STREQUAL "native") OUTPUT_STRIP_TRAILING_WHITESPACE) if("${LLVM_CONFIG_VERSION}" VERSION_LESS 11) - message(FATAL_ERROR "expected LLVM 11.x but found ${LLVM_CONFIG_VERSION}") + message(FATAL_ERROR "expected LLVM 11.x but found ${LLVM_CONFIG_VERSION} using ${LLVM_CONFIG_EXE}") endif() if("${LLVM_CONFIG_VERSION}" VERSION_EQUAL 12) - message(FATAL_ERROR "expected LLVM 11.x but found ${LLVM_CONFIG_VERSION}") + message(FATAL_ERROR "expected LLVM 11.x but found ${LLVM_CONFIG_VERSION} using ${LLVM_CONFIG_EXE}") endif() if("${LLVM_CONFIG_VERSION}" VERSION_GREATER 11) - message(FATAL_ERROR "expected LLVM 11.x but found ${LLVM_CONFIG_VERSION}") + message(FATAL_ERROR "expected LLVM 11.x but found ${LLVM_CONFIG_VERSION} using ${LLVM_CONFIG_EXE}") endif() execute_process( @@ -72,12 +72,13 @@ elseif("${ZIG_TARGET_TRIPLE}" STREQUAL "native") function(NEED_TARGET TARGET_NAME) list (FIND LLVM_TARGETS_BUILT "${TARGET_NAME}" _index) if (${_index} EQUAL -1) - message(FATAL_ERROR "LLVM is missing target ${TARGET_NAME}. Zig requires LLVM to be built with all default targets enabled.") + message(FATAL_ERROR "LLVM (according to ${LLVM_CONFIG_EXE}) is missing target ${TARGET_NAME}. Zig requires LLVM to be built with all default targets enabled.") endif() endfunction(NEED_TARGET) NEED_TARGET("AArch64") NEED_TARGET("AMDGPU") NEED_TARGET("ARM") + NEED_TARGET("AVR") NEED_TARGET("BPF") NEED_TARGET("Hexagon") NEED_TARGET("Lanai") @@ -141,8 +142,7 @@ elseif("${ZIG_TARGET_TRIPLE}" STREQUAL "native") link_directories("${LLVM_LIBDIRS}") else() # Here we assume that we're cross compiling with Zig, of course. No reason - # to support more complicated setups. We also assume the experimental target - # AVR is enabled. + # to support more complicated setups. macro(FIND_AND_ADD_LLVM_LIB _libname_) string(TOUPPER ${_libname_} _prettylibname_) diff --git a/deps/dbg-macro/LICENSE b/deps/dbg-macro/LICENSE deleted file mode 100644 index 243854e613..0000000000 --- a/deps/dbg-macro/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2019 David Peter - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/deps/dbg-macro/README.md b/deps/dbg-macro/README.md deleted file mode 100644 index a142d31432..0000000000 --- a/deps/dbg-macro/README.md +++ /dev/null @@ -1,172 +0,0 @@ -# `dbg(…)` - -[![Build Status](https://travis-ci.org/sharkdp/dbg-macro.svg?branch=master)](https://travis-ci.org/sharkdp/dbg-macro) [![Build status](https://ci.appveyor.com/api/projects/status/vmo9rw4te2wifkul/branch/master?svg=true)](https://ci.appveyor.com/project/sharkdp/dbg-macro) [![Try it online](https://img.shields.io/badge/try-online-f34b7d.svg)](https://repl.it/@sharkdp/dbg-macro-demo) [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](dbg.h) - -*A macro for `printf`-style debugging fans.* - -Debuggers are great. But sometimes you just don't have the time or patience to set -up everything correctly and just want a quick way to inspect some values at runtime. - -This projects provides a [single header file](dbg.h) with a `dbg(…)` -macro that can be used in all circumstances where you would typically write -`printf("…", …)` or `std::cout << …`. But it comes with a few extras. - -## Examples - -``` c++ -#include -#include - -// You can use "dbg(..)" in expressions: -int factorial(int n) { - if (dbg(n <= 1)) { - return dbg(1); - } else { - return dbg(n * factorial(n - 1)); - } -} - -int main() { - std::string message = "hello"; - dbg(message); // [example.cpp:15 (main)] message = "hello" (std::string) - - const int a = 2; - const int b = dbg(3 * a) + 1; // [example.cpp:18 (main)] 3 * a = 6 (int) - - std::vector numbers{b, 13, 42}; - dbg(numbers); // [example.cpp:21 (main)] numbers = {7, 13, 42} (size: 3) (std::vector) - - dbg("this line is executed"); // [example.cpp:23 (main)] this line is executed - - factorial(4); - - return 0; -} -``` - -The code above produces this output ([try it yourself](https://repl.it/@sharkdp/dbg-macro-demo)): - -![dbg(…) macro output](https://i.imgur.com/NHEYk9A.png) - -## Features - - * Easy to read, colorized output (colors auto-disable when the output is not an interactive terminal) - * Prints file name, line number, function name and the original expression - * Adds type information for the printed-out value - * Specialized pretty-printers for containers, pointers, string literals, enums, `std::optional`, etc. - * Can be used inside expressions (passing through the original value) - * The `dbg.h` header issues a compiler warning when included (so you don't forget to remove it). - * Compatible and tested with C++11, C++14 and C++17. - -## Installation - -To make this practical, the `dbg.h` header should to be readily available from all kinds of different -places and in all kinds of environments. The quick & dirty way is to actually copy the header file -to `/usr/include` or to clone the repository and symlink `dbg.h` to `/usr/include/dbg.h`. -``` bash -git clone https://github.com/sharkdp/dbg-macro -sudo ln -s $(readlink -f dbg-macro/dbg.h) /usr/include/dbg.h -``` -If you don't want to make untracked changes to your filesystem, check below if there is a package for -your operating system or package manager. - -### On Arch Linux - -You can install [`dbg-macro` from the AUR](https://aur.archlinux.org/packages/dbg-macro/): -``` bash -yay -S dbg-macro -``` - -### With vcpkg - -You can install the [`dbg-macro` port](https://github.com/microsoft/vcpkg/tree/master/ports/dbg-macro) via: -``` bash -vcpkg install dbg-macro -``` - -## Configuration - -* Set the `DBG_MACRO_DISABLE` flag to disable the `dbg(…)` macro (i.e. to make it a no-op). -* Set the `DBG_MACRO_NO_WARNING` flag to disable the *"'dbg.h' header is included in your code base"* warnings. - -## Advanced features - -### Hexadecimal, octal and binary format - -If you want to format integers in hexadecimal, octal or binary representation, you can -simply wrap them in `dbg::hex(…)`, `dbg::oct(…)` or `dbg::bin(…)`: -```c++ -const uint32_t secret = 12648430; -dbg(dbg::hex(secret)); -``` - -### Printing type names - -`dbg(…)` already prints the type for each value in parenthesis (see screenshot above). But -sometimes you just want to print a type (maybe because you don't have a value for that type). -In this case, you can use the `dbg::type()` helper to pretty-print a given type `T`. -For example: -```c++ -template -void my_function_template() { - using MyDependentType = typename std::remove_reference::type&&; - dbg(dbg::type()); -} -``` - -### Print the current time - -To print a timestamp, you can use the `dbg::time()` helper: -```c++ -dbg(dbg::time()); -``` - -### Customization - -If you want `dbg(…)` to work for your custom datatype, you can simply overload `operator<<` for -`std::ostream&`: -```c++ -std::ostream& operator<<(std::ostream& out, const user_defined_type& v) { - out << "…"; - return out; -} -``` - -If you want to modify the type name that is printed by `dbg(…)`, you can add a custom -`get_type_name` overload: -```c++ -// Customization point for type information -namespace dbg { - std::string get_type_name(type_tag) { - return "truth value"; - } -} -``` - -## Development - -If you want to contribute to `dbg-macro`, here is how you can build the tests and demos: - -Make sure that the submodule(s) are up to date: -```bash -git submodule update --init -``` - -Then, use the typical `cmake` workflow. Usage of `-DCMAKE_CXX_STANDARD=17` is optional, -but recommended in order to have the largest set of features enabled: -```bash -mkdir build -cd build -cmake .. -DCMAKE_CXX_STANDARD=17 -make -``` - -To run the tests, simply call: -```bash -make test -``` -You can find the unit tests in `tests/basic.cpp`. - -## Acknowledgement - -This project is inspired by Rusts [`dbg!(…)` macro](https://doc.rust-lang.org/std/macro.dbg.html). diff --git a/deps/dbg-macro/dbg.h b/deps/dbg-macro/dbg.h deleted file mode 100644 index 3a76130514..0000000000 --- a/deps/dbg-macro/dbg.h +++ /dev/null @@ -1,711 +0,0 @@ -/***************************************************************************** - - dbg(...) macro - -License (MIT): - - Copyright (c) 2019 David Peter - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - -*****************************************************************************/ - -#ifndef DBG_MACRO_DBG_H -#define DBG_MACRO_DBG_H - -#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) -#define DBG_MACRO_UNIX -#elif defined(_MSC_VER) -#define DBG_MACRO_WINDOWS -#endif - -#ifndef DBG_MACRO_NO_WARNING -#pragma message("WARNING: the 'dbg.h' header is included in your code base") -#endif // DBG_MACRO_NO_WARNING - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef DBG_MACRO_UNIX -#include -#endif - -#if __cplusplus >= 201703L || defined(_MSC_VER) -#define DBG_MACRO_CXX_STANDARD 17 -#elif __cplusplus >= 201402L -#define DBG_MACRO_CXX_STANDARD 14 -#else -#define DBG_MACRO_CXX_STANDARD 11 -#endif - -#if DBG_MACRO_CXX_STANDARD >= 17 -#include -#include -#endif - -namespace dbg { - -#ifdef DBG_MACRO_UNIX -inline bool isColorizedOutputEnabled() { - return isatty(fileno(stderr)); -} -#else -inline bool isColorizedOutputEnabled() { - return true; -} -#endif - -struct time {}; - -namespace pretty_function { - -// Compiler-agnostic version of __PRETTY_FUNCTION__ and constants to -// extract the template argument in `type_name_impl` - -#if defined(__clang__) -#define DBG_MACRO_PRETTY_FUNCTION __PRETTY_FUNCTION__ -static constexpr size_t PREFIX_LENGTH = - sizeof("const char *dbg::type_name_impl() [T = ") - 1; -static constexpr size_t SUFFIX_LENGTH = sizeof("]") - 1; -#elif defined(__GNUC__) && !defined(__clang__) -#define DBG_MACRO_PRETTY_FUNCTION __PRETTY_FUNCTION__ -static constexpr size_t PREFIX_LENGTH = - sizeof("const char* dbg::type_name_impl() [with T = ") - 1; -static constexpr size_t SUFFIX_LENGTH = sizeof("]") - 1; -#elif defined(_MSC_VER) -#define DBG_MACRO_PRETTY_FUNCTION __FUNCSIG__ -static constexpr size_t PREFIX_LENGTH = - sizeof("const char *__cdecl dbg::type_name_impl<") - 1; -static constexpr size_t SUFFIX_LENGTH = sizeof(">(void)") - 1; -#else -#error "This compiler is currently not supported by dbg_macro." -#endif - -} // namespace pretty_function - -// Formatting helpers - -template -struct print_formatted { - static_assert(std::is_integral::value, - "Only integral types are supported."); - - print_formatted(T value, int numeric_base) - : inner(value), base(numeric_base) {} - - operator T() const { return inner; } - - const char* prefix() const { - switch (base) { - case 8: - return "0o"; - case 16: - return "0x"; - case 2: - return "0b"; - default: - return ""; - } - } - - T inner; - int base; -}; - -template -print_formatted hex(T value) { - return print_formatted{value, 16}; -} - -template -print_formatted oct(T value) { - return print_formatted{value, 8}; -} - -template -print_formatted bin(T value) { - return print_formatted{value, 2}; -} - -// Implementation of 'type_name()' - -template -const char* type_name_impl() { - return DBG_MACRO_PRETTY_FUNCTION; -} - -template -struct type_tag {}; - -template -std::string get_type_name(type_tag) { - namespace pf = pretty_function; - - std::string type = type_name_impl(); - return type.substr(pf::PREFIX_LENGTH, - type.size() - pf::PREFIX_LENGTH - pf::SUFFIX_LENGTH); -} - -template -std::string type_name() { - if (std::is_volatile::value) { - if (std::is_pointer::value) { - return type_name::type>() + " volatile"; - } else { - return "volatile " + type_name::type>(); - } - } - if (std::is_const::value) { - if (std::is_pointer::value) { - return type_name::type>() + " const"; - } else { - return "const " + type_name::type>(); - } - } - if (std::is_pointer::value) { - return type_name::type>() + "*"; - } - if (std::is_lvalue_reference::value) { - return type_name::type>() + "&"; - } - if (std::is_rvalue_reference::value) { - return type_name::type>() + "&&"; - } - return get_type_name(type_tag{}); -} - -inline std::string get_type_name(type_tag) { - return "short"; -} - -inline std::string get_type_name(type_tag) { - return "unsigned short"; -} - -inline std::string get_type_name(type_tag) { - return "long"; -} - -inline std::string get_type_name(type_tag) { - return "unsigned long"; -} - -inline std::string get_type_name(type_tag) { - return "std::string"; -} - -template -std::string get_type_name(type_tag>>) { - return "std::vector<" + type_name() + ">"; -} - -template -std::string get_type_name(type_tag>) { - return "std::pair<" + type_name() + ", " + type_name() + ">"; -} - -template -std::string type_list_to_string() { - std::string result; - auto unused = {(result += type_name() + ", ", 0)..., 0}; - static_cast(unused); - - if (sizeof...(T) > 0) { - result.pop_back(); - result.pop_back(); - } - return result; -} - -template -std::string get_type_name(type_tag>) { - return "std::tuple<" + type_list_to_string() + ">"; -} - -template -inline std::string get_type_name(type_tag>) { - return type_name(); -} - -// Implementation of 'is_detected' to specialize for container-like types - -namespace detail_detector { - -struct nonesuch { - nonesuch() = delete; - ~nonesuch() = delete; - nonesuch(nonesuch const&) = delete; - void operator=(nonesuch const&) = delete; -}; - -template -using void_t = void; - -template - class Op, - class... Args> -struct detector { - using value_t = std::false_type; - using type = Default; -}; - -template class Op, class... Args> -struct detector>, Op, Args...> { - using value_t = std::true_type; - using type = Op; -}; - -} // namespace detail_detector - -template