/* Copyright (C) 1991-2020 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see . */ /* This header is separate from features.h so that the compiler can include it implicitly at the start of every compilation. It must not itself include or any other header that includes because the implicit include comes before any feature test macros that may be defined in a source file before it first explicitly includes a system header. GCC knows the name of this header in order to preinclude it. */ /* glibc's intent is to support the IEC 559 math functionality, real and complex. If the GCC (4.9 and later) predefined macros specifying compiler intent are available, use them to determine whether the overall intent is to support these features; otherwise, presume an older compiler has intent to support these features and define these macros by default. */ /* wchar_t uses Unicode 10.0.0. Version 10.0 of the Unicode Standard is synchronized with ISO/IEC 10646:2017, fifth edition, plus the following additions from Amendment 1 to the fifth edition: - 56 emoji characters - 285 hentaigana - 3 additional Zanabazar Square characters */ // Copyright (c) 2019 Bastien Penavayre // // This software is released under the MIT License. // https://opensource.org/licenses/MIT // Copyright (c) 2019 Bastien Penavayre // // This software is released under the MIT License. // https://opensource.org/licenses/MIT // Copyright (c) 2019 Bastien Penavayre // // This software is released under the MIT License. // https://opensource.org/licenses/MIT namespace unconstexpr { // unique id section using id_value = const int *; template struct id_t {}; template struct unique_id { static constexpr int value = 0; constexpr unique_id(T const &) {} constexpr operator id_value() const { return &value; } }; /** The following is one of the base of this hack! This works because the conversion from unique_id to bool is delayed, therefore the lambda is a new one at each instantiation of a template depending on that non-type template which leads to 'name' to have a different value at each deduction */ } // namespace unconstexpr // Copyright (c) 2019 Bastien Penavayre // // This software is released under the MIT License. // https://opensource.org/licenses/MIT namespace unconstexpr { template struct value_t { static constexpr auto value = V; }; template struct value_lambda { static constexpr auto value = Lambda{}(); }; } // namespace unconstexpr // force each call to be a new template instanciation // checks that Meta is a meta_var // simple workaround for lack of concepts namespace unconstexpr { template constexpr auto current_index(Meta const& = {}) { constexpr auto idx = Meta::template last_index(); return idx; } template constexpr auto current_value(Meta const& = {}) { constexpr auto idx = current_index(); return Meta::template value(); } namespace increment_hack { /** To circomvent bug in clang: Constexpr variables aren't implicitly captured in lambda expressions if we are in a template context. As some of the following constexpr variable might be invalid non-type template parameter, we defines them here so that we can access them from a default-construstible lambda and pass it around. */ template struct increment_info { static constexpr auto idx = current_index(); static constexpr auto value = Meta::template value(); static constexpr auto nvalue = value + ValueInc::value; }; } // namespace increment_hack template , id_value Id = unique_id([] {}), bool = Meta::is_meta_var> constexpr auto increment(Meta const& = {}) { using hack = increment_hack::template increment_info; constexpr auto idx = hack::idx; constexpr auto value = hack::value; constexpr auto nvalue = hack::nvalue; constexpr auto nidx = idx + Meta::increment; constexpr auto lambda_next = [] { return hack::nvalue; }; using value_holder = value_lambda; static_assert(Meta::template set_value); if constexpr (postincrement) return value; else return nvalue; } template constexpr auto set(Meta const& = {}, value_t const& = {}) { constexpr auto idx = current_index(); constexpr auto nidx = idx + Meta::increment; using holder = value_t; static_assert(Meta::template set_value); return Value; } template constexpr auto set(Meta const& = {}, Lambda const& = {}) { constexpr auto idx = current_index(); constexpr auto nidx = idx + Meta::increment; using holder = value_lambda; static_assert(Meta::template set_value); return holder::value; } } // namespace unconstexpr // Copyright (c) 2019 Bastien Penavayre // // This software is released under the MIT License. // https://opensource.org/licenses/MIT namespace unconstexpr { template struct meta_value { template struct flagCheck { template friend constexpr auto unconstexpr_adl(flagCheck, id_t const &); }; template struct flagGet { template friend constexpr auto unconstexpr_adl(flagGet, id_t const &); }; template > struct writer { template friend constexpr auto unconstexpr_adl(flagCheck, id_t const &) { return true; } template friend constexpr auto unconstexpr_adl(flagGet, id_t const &) { return ValueHolder::value; } }; static_assert(sizeof(writer<0, value_t>)); template {}, T{}))> static constexpr bool exists(int) { return true; } template static constexpr bool exists(float) { return false; } template static constexpr auto last_index() { using unique_type = id_t; constexpr bool ok = exists(int{}); if constexpr (ok) return last_index(); else return Index; } template static constexpr auto value() { using unique_type = id_t; return unconstexpr_adl(flagGet{}, unique_type{}); } static constexpr bool is_meta_var = true; static constexpr auto increment = Inc; template static constexpr bool set_value = sizeof(writer); }; } // namespace unconstexpr // Copyright (c) 2019 Bastien Penavayre // // This software is released under the MIT License. // https://opensource.org/licenses/MIT namespace unconstexpr { template constexpr auto operator*(Meta const &) { return current_value(); } template constexpr auto operator++(Meta const &, Opt...) { constexpr bool is_postincrement = sizeof...(Opt) != 0; using inc = value_t; return increment(); } template constexpr auto operator--(Meta const &, Opt...) { constexpr bool is_postincrement = sizeof...(Opt) != 0; using inc = value_t<-1 * Meta::increment>; return increment(); } template constexpr auto operator+=(Meta const &c, value_t const &) { static_assert(sizeof(increment, Id>())); return c; } template constexpr auto operator+=(Meta const &c, Lambda const &) { static_assert(sizeof(increment, Id>())); return c; } template constexpr auto operator<<(Meta const &c, value_t const &) { static_assert(sizeof(set())); return c; } template constexpr auto operator<<(Meta const &c, Holder const &) { static_assert(sizeof(set())); return c; } } // namespace unconstexpr