Fix Weight::create() when std::from_chars() is used
[xapian.git] / xapian-bindings / m4 / ax_cxx_compile_stdcxx.m4
bloba9c990e3694455a2d354efcda04fe007613612f6
1 # ===========================================================================
2 #  https://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html
3 # ===========================================================================
5 # SYNOPSIS
7 #   AX_CXX_COMPILE_STDCXX(VERSION, [ext|noext], [mandatory|optional])
9 # DESCRIPTION
11 #   Check for baseline language coverage in the compiler for the specified
12 #   version of the C++ standard.  If necessary, add switches to CXX and
13 #   CXXCPP to enable support.  VERSION may be '11', '14', '17', or '20' for
14 #   the respective C++ standard version.
16 #   The second argument, if specified, indicates whether you insist on an
17 #   extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g.
18 #   -std=c++11).  If neither is specified, you get whatever works, with
19 #   preference for no added switch, and then for an extended mode.
21 #   The third argument, if specified 'mandatory' or if left unspecified,
22 #   indicates that baseline support for the specified C++ standard is
23 #   required and that the macro should error out if no mode with that
24 #   support is found.  If specified 'optional', then configuration proceeds
25 #   regardless, after defining HAVE_CXX${VERSION} if and only if a
26 #   supporting mode is found.
28 # LICENSE
30 #   Copyright (c) 2008 Benjamin Kosnik <bkoz@redhat.com>
31 #   Copyright (c) 2012 Zack Weinberg <zackw@panix.com>
32 #   Copyright (c) 2013 Roy Stogner <roystgnr@ices.utexas.edu>
33 #   Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov <sokolov@google.com>
34 #   Copyright (c) 2015 Paul Norman <penorman@mac.com>
35 #   Copyright (c) 2015 Moritz Klammler <moritz@klammler.eu>
36 #   Copyright (c) 2016, 2018 Krzesimir Nowak <qdlacz@gmail.com>
37 #   Copyright (c) 2019 Enji Cooper <yaneurabeya@gmail.com>
38 #   Copyright (c) 2020 Jason Merrill <jason@redhat.com>
39 #   Copyright (c) 2021 Jörn Heusipp <osmanx@problemloesungsmaschine.de>
41 #   Copying and distribution of this file, with or without modification, are
42 #   permitted in any medium without royalty provided the copyright notice
43 #   and this notice are preserved.  This file is offered as-is, without any
44 #   warranty.
46 #serial 16
48 dnl  This macro is based on the code from the AX_CXX_COMPILE_STDCXX_11 macro
49 dnl  (serial version number 13).
51 AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl
52   m4_if([$1], [11], [ax_cxx_compile_alternatives="11 0x"],
53         [$1], [14], [ax_cxx_compile_alternatives="14 1y"],
54         [$1], [17], [ax_cxx_compile_alternatives="17 1z"],
55         [$1], [20], [ax_cxx_compile_alternatives="20"],
56         [m4_fatal([invalid first argument `$1' to AX_CXX_COMPILE_STDCXX])])dnl
57   m4_if([$2], [], [],
58         [$2], [ext], [],
59         [$2], [noext], [],
60         [m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX])])dnl
61   m4_if([$3], [], [ax_cxx_compile_cxx$1_required=true],
62         [$3], [mandatory], [ax_cxx_compile_cxx$1_required=true],
63         [$3], [optional], [ax_cxx_compile_cxx$1_required=false],
64         [m4_fatal([invalid third argument `$3' to AX_CXX_COMPILE_STDCXX])])
65   AC_LANG_PUSH([C++])dnl
66   ac_success=no
68   m4_if([$2], [], [dnl
69     AC_CACHE_CHECK(whether $CXX supports C++$1 features by default,
70                    ax_cv_cxx_compile_cxx$1,
71       [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])],
72         [ax_cv_cxx_compile_cxx$1=yes],
73         [ax_cv_cxx_compile_cxx$1=no])])
74     if test x$ax_cv_cxx_compile_cxx$1 = xyes; then
75       ac_success=yes
76     fi])
78   m4_if([$2], [noext], [], [dnl
79   if test x$ac_success = xno; then
80     for alternative in ${ax_cxx_compile_alternatives}; do
81       switch="-std=gnu++${alternative}"
82       cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch])
83       AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch,
84                      $cachevar,
85         [ac_save_CXX="$CXX"
86          CXX="$CXX $switch"
87          AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])],
88           [eval $cachevar=yes],
89           [eval $cachevar=no])
90          CXX="$ac_save_CXX"])
91       if eval test x\$$cachevar = xyes; then
92         CXX="$CXX $switch"
93         if test -n "$CXXCPP" ; then
94           CXXCPP="$CXXCPP $switch"
95         fi
96         ac_success=yes
97         break
98       fi
99     done
100   fi])
102   m4_if([$2], [ext], [], [dnl
103   if test x$ac_success = xno; then
104     dnl HP's aCC needs +std=c++11 according to:
105     dnl http://h21007.www2.hp.com/portal/download/files/unprot/aCxx/PDF_Release_Notes/769149-001.pdf
106     dnl Cray's crayCC needs "-h std=c++11"
107     dnl MSVC needs -std:c++NN for C++17 and later (default is C++14)
108     for alternative in ${ax_cxx_compile_alternatives}; do
109       for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}" MSVC; do
110         if test x"$switch" = xMSVC; then
111           dnl AS_TR_SH maps both `:` and `=` to `_` so -std:c++17 would collide
112           dnl with -std=c++17.  We suffix the cache variable name with _MSVC to
113           dnl avoid this.
114           switch=-std:c++${alternative}
115           cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_${switch}_MSVC])
116         else
117           cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch])
118         fi
119         AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch,
120                        $cachevar,
121           [ac_save_CXX="$CXX"
122            CXX="$CXX $switch"
123            AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])],
124             [eval $cachevar=yes],
125             [eval $cachevar=no])
126            CXX="$ac_save_CXX"])
127         if eval test x\$$cachevar = xyes; then
128           CXX="$CXX $switch"
129           if test -n "$CXXCPP" ; then
130             CXXCPP="$CXXCPP $switch"
131           fi
132           ac_success=yes
133           break
134         fi
135       done
136       if test x$ac_success = xyes; then
137         break
138       fi
139     done
140   fi])
141   AC_LANG_POP([C++])
142   if test x$ax_cxx_compile_cxx$1_required = xtrue; then
143     if test x$ac_success = xno; then
144       AC_MSG_ERROR([*** A compiler with support for C++$1 language features is required.])
145     fi
146   fi
147   if test x$ac_success = xno; then
148     HAVE_CXX$1=0
149     AC_MSG_NOTICE([No compiler with C++$1 support was found])
150   else
151     HAVE_CXX$1=1
152     AC_DEFINE(HAVE_CXX$1,1,
153               [define if the compiler supports basic C++$1 syntax])
154   fi
155   AC_SUBST(HAVE_CXX$1)
159 dnl  Test body for checking C++11 support
161 m4_define([_AX_CXX_COMPILE_STDCXX_testbody_11],
162   _AX_CXX_COMPILE_STDCXX_testbody_new_in_11
165 dnl  Test body for checking C++14 support
167 m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14],
168   _AX_CXX_COMPILE_STDCXX_testbody_new_in_11
169   _AX_CXX_COMPILE_STDCXX_testbody_new_in_14
172 dnl  Test body for checking C++17 support
174 m4_define([_AX_CXX_COMPILE_STDCXX_testbody_17],
175   _AX_CXX_COMPILE_STDCXX_testbody_new_in_11
176   _AX_CXX_COMPILE_STDCXX_testbody_new_in_14
177   _AX_CXX_COMPILE_STDCXX_testbody_new_in_17
180 dnl  Test body for checking C++20 support
182 m4_define([_AX_CXX_COMPILE_STDCXX_testbody_20],
183   _AX_CXX_COMPILE_STDCXX_testbody_new_in_11
184   _AX_CXX_COMPILE_STDCXX_testbody_new_in_14
185   _AX_CXX_COMPILE_STDCXX_testbody_new_in_17
186   _AX_CXX_COMPILE_STDCXX_testbody_new_in_20
190 dnl  Tests for new features in C++11
192 m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_11], [[
194 // If the compiler admits that it is not ready for C++11, why torture it?
195 // Hopefully, this will speed up the test.
197 #ifndef __cplusplus
199 #error "This is not a C++ compiler"
201 // MSVC always sets __cplusplus to 199711L in older versions; newer versions
202 // only set it correctly if /Zc:__cplusplus is specified as well as a
203 // /std:c++NN switch:
204 // https://devblogs.microsoft.com/cppblog/msvc-now-correctly-reports-__cplusplus/
205 #elif __cplusplus < 201103L && !defined _MSC_VER
207 #error "This is not a C++11 compiler"
209 #else
211 namespace cxx11
214   namespace test_static_assert
215   {
217     template <typename T>
218     struct check
219     {
220       static_assert(sizeof(int) <= sizeof(T), "not big enough");
221     };
223   }
225   namespace test_final_override
226   {
228     struct Base
229     {
230       virtual ~Base() {}
231       virtual void f() {}
232     };
234     struct Derived : public Base
235     {
236       virtual ~Derived() override {}
237       virtual void f() override {}
238     };
240   }
242   namespace test_double_right_angle_brackets
243   {
245     template < typename T >
246     struct check {};
248     typedef check<void> single_type;
249     typedef check<check<void>> double_type;
250     typedef check<check<check<void>>> triple_type;
251     typedef check<check<check<check<void>>>> quadruple_type;
253   }
255   namespace test_decltype
256   {
258     int
259     f()
260     {
261       int a = 1;
262       decltype(a) b = 2;
263       return a + b;
264     }
266   }
268   namespace test_type_deduction
269   {
271     template < typename T1, typename T2 >
272     struct is_same
273     {
274       static const bool value = false;
275     };
277     template < typename T >
278     struct is_same<T, T>
279     {
280       static const bool value = true;
281     };
283     template < typename T1, typename T2 >
284     auto
285     add(T1 a1, T2 a2) -> decltype(a1 + a2)
286     {
287       return a1 + a2;
288     }
290     int
291     test(const int c, volatile int v)
292     {
293       static_assert(is_same<int, decltype(0)>::value == true, "");
294       static_assert(is_same<int, decltype(c)>::value == false, "");
295       static_assert(is_same<int, decltype(v)>::value == false, "");
296       auto ac = c;
297       auto av = v;
298       auto sumi = ac + av + 'x';
299       auto sumf = ac + av + 1.0;
300       static_assert(is_same<int, decltype(ac)>::value == true, "");
301       static_assert(is_same<int, decltype(av)>::value == true, "");
302       static_assert(is_same<int, decltype(sumi)>::value == true, "");
303       static_assert(is_same<int, decltype(sumf)>::value == false, "");
304       static_assert(is_same<int, decltype(add(c, v))>::value == true, "");
305       return (sumf > 0.0) ? sumi : add(c, v);
306     }
308   }
310   namespace test_noexcept
311   {
313     int f() { return 0; }
314     int g() noexcept { return 0; }
316     static_assert(noexcept(f()) == false, "");
317     static_assert(noexcept(g()) == true, "");
319   }
321   namespace test_constexpr
322   {
324     template < typename CharT >
325     unsigned long constexpr
326     strlen_c_r(const CharT *const s, const unsigned long acc) noexcept
327     {
328       return *s ? strlen_c_r(s + 1, acc + 1) : acc;
329     }
331     template < typename CharT >
332     unsigned long constexpr
333     strlen_c(const CharT *const s) noexcept
334     {
335       return strlen_c_r(s, 0UL);
336     }
338     static_assert(strlen_c("") == 0UL, "");
339     static_assert(strlen_c("1") == 1UL, "");
340     static_assert(strlen_c("example") == 7UL, "");
341     static_assert(strlen_c("another\0example") == 7UL, "");
343   }
345   namespace test_rvalue_references
346   {
348     template < int N >
349     struct answer
350     {
351       static constexpr int value = N;
352     };
354     answer<1> f(int&)       { return answer<1>(); }
355     answer<2> f(const int&) { return answer<2>(); }
356     answer<3> f(int&&)      { return answer<3>(); }
358     void
359     test()
360     {
361       int i = 0;
362       const int c = 0;
363       static_assert(decltype(f(i))::value == 1, "");
364       static_assert(decltype(f(c))::value == 2, "");
365       static_assert(decltype(f(0))::value == 3, "");
366     }
368   }
370   namespace test_uniform_initialization
371   {
373     struct test
374     {
375       static const int zero {};
376       static const int one {1};
377     };
379     static_assert(test::zero == 0, "");
380     static_assert(test::one == 1, "");
382   }
384   namespace test_lambdas
385   {
387     void
388     test1()
389     {
390       auto lambda1 = [](){};
391       auto lambda2 = lambda1;
392       lambda1();
393       lambda2();
394     }
396     int
397     test2()
398     {
399       auto a = [](int i, int j){ return i + j; }(1, 2);
400       auto b = []() -> int { return '0'; }();
401       auto c = [=](){ return a + b; }();
402       auto d = [&](){ return c; }();
403       auto e = [a, &b](int x) mutable {
404         const auto identity = [](int y){ return y; };
405         for (auto i = 0; i < a; ++i)
406           a += b--;
407         return x + identity(a + b);
408       }(0);
409       return a + b + c + d + e;
410     }
412     int
413     test3()
414     {
415       const auto nullary = [](){ return 0; };
416       const auto unary = [](int x){ return x; };
417       using nullary_t = decltype(nullary);
418       using unary_t = decltype(unary);
419       const auto higher1st = [](nullary_t f){ return f(); };
420       const auto higher2nd = [unary](nullary_t f1){
421         return [unary, f1](unary_t f2){ return f2(unary(f1())); };
422       };
423       return higher1st(nullary) + higher2nd(nullary)(unary);
424     }
426   }
428   namespace test_variadic_templates
429   {
431     template <int...>
432     struct sum;
434     template <int N0, int... N1toN>
435     struct sum<N0, N1toN...>
436     {
437       static constexpr auto value = N0 + sum<N1toN...>::value;
438     };
440     template <>
441     struct sum<>
442     {
443       static constexpr auto value = 0;
444     };
446     static_assert(sum<>::value == 0, "");
447     static_assert(sum<1>::value == 1, "");
448     static_assert(sum<23>::value == 23, "");
449     static_assert(sum<1, 2>::value == 3, "");
450     static_assert(sum<5, 5, 11>::value == 21, "");
451     static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, "");
453   }
455   // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae
456   // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function
457   // because of this.
458   namespace test_template_alias_sfinae
459   {
461     struct foo {};
463     template<typename T>
464     using member = typename T::member_type;
466     template<typename T>
467     void func(...) {}
469     template<typename T>
470     void func(member<T>*) {}
472     void test();
474     void test() { func<foo>(0); }
476   }
478 }  // namespace cxx11
480 #endif  // __cplusplus >= 201103L
485 dnl  Tests for new features in C++14
487 m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_14], [[
489 // If the compiler admits that it is not ready for C++14, why torture it?
490 // Hopefully, this will speed up the test.
492 #ifndef __cplusplus
494 #error "This is not a C++ compiler"
496 #elif __cplusplus < 201402L && !defined _MSC_VER
498 #error "This is not a C++14 compiler"
500 #else
502 namespace cxx14
505   namespace test_polymorphic_lambdas
506   {
508     int
509     test()
510     {
511       const auto lambda = [](auto&&... args){
512         const auto istiny = [](auto x){
513           return (sizeof(x) == 1UL) ? 1 : 0;
514         };
515         const int aretiny[] = { istiny(args)... };
516         return aretiny[0];
517       };
518       return lambda(1, 1L, 1.0f, '1');
519     }
521   }
523   namespace test_binary_literals
524   {
526     constexpr auto ivii = 0b0000000000101010;
527     static_assert(ivii == 42, "wrong value");
529   }
531   namespace test_generalized_constexpr
532   {
534     template < typename CharT >
535     constexpr unsigned long
536     strlen_c(const CharT *const s) noexcept
537     {
538       auto length = 0UL;
539       for (auto p = s; *p; ++p)
540         ++length;
541       return length;
542     }
544     static_assert(strlen_c("") == 0UL, "");
545     static_assert(strlen_c("x") == 1UL, "");
546     static_assert(strlen_c("test") == 4UL, "");
547     static_assert(strlen_c("another\0test") == 7UL, "");
549   }
551   namespace test_lambda_init_capture
552   {
554     int
555     test()
556     {
557       auto x = 0;
558       const auto lambda1 = [a = x](int b){ return a + b; };
559       const auto lambda2 = [a = lambda1(x)](){ return a; };
560       return lambda2();
561     }
563   }
565   namespace test_digit_separators
566   {
568     constexpr auto ten_million = 100'000'000;
569     static_assert(ten_million == 100000000, "");
571   }
573   namespace test_return_type_deduction
574   {
576     auto f(int& x) { return x; }
577     decltype(auto) g(int& x) { return x; }
579     template < typename T1, typename T2 >
580     struct is_same
581     {
582       static constexpr auto value = false;
583     };
585     template < typename T >
586     struct is_same<T, T>
587     {
588       static constexpr auto value = true;
589     };
591     int
592     test()
593     {
594       auto x = 0;
595       static_assert(is_same<int, decltype(f(x))>::value, "");
596       static_assert(is_same<int&, decltype(g(x))>::value, "");
597       return x;
598     }
600   }
602 }  // namespace cxx14
604 #endif  // __cplusplus >= 201402L
609 dnl  Tests for new features in C++17
611 m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_17], [[
613 // If the compiler admits that it is not ready for C++17, why torture it?
614 // Hopefully, this will speed up the test.
616 #ifndef __cplusplus
618 #error "This is not a C++ compiler"
620 #elif __cplusplus < 201703L && !defined _MSC_VER
622 #error "This is not a C++17 compiler"
624 #else
626 #include <initializer_list>
627 #include <utility>
628 #include <type_traits>
630 namespace cxx17
633   namespace test_constexpr_lambdas
634   {
636     constexpr int foo = [](){return 42;}();
638   }
640   namespace test::nested_namespace::definitions
641   {
643   }
645   namespace test_fold_expression
646   {
648     template<typename... Args>
649     int multiply(Args... args)
650     {
651       return (args * ... * 1);
652     }
654     template<typename... Args>
655     bool all(Args... args)
656     {
657       return (args && ...);
658     }
660   }
662   namespace test_extended_static_assert
663   {
665     static_assert (true);
667   }
669   namespace test_auto_brace_init_list
670   {
672     auto foo = {5};
673     auto bar {5};
675     static_assert(std::is_same<std::initializer_list<int>, decltype(foo)>::value);
676     static_assert(std::is_same<int, decltype(bar)>::value);
677   }
679   namespace test_typename_in_template_template_parameter
680   {
682     template<template<typename> typename X> struct D;
684   }
686   namespace test_fallthrough_nodiscard_maybe_unused_attributes
687   {
689     int f1()
690     {
691       return 42;
692     }
694     [[nodiscard]] int f2()
695     {
696       [[maybe_unused]] auto unused = f1();
698       switch (f1())
699       {
700       case 17:
701         f1();
702         [[fallthrough]];
703       case 42:
704         f1();
705       }
706       return f1();
707     }
709   }
711   namespace test_extended_aggregate_initialization
712   {
714     struct base1
715     {
716       int b1, b2 = 42;
717     };
719     struct base2
720     {
721       base2() {
722         b3 = 42;
723       }
724       int b3;
725     };
727     struct derived : base1, base2
728     {
729         int d;
730     };
732     derived d1 {{1, 2}, {}, 4};  // full initialization
733     derived d2 {{}, {}, 4};      // value-initialized bases
735   }
737   namespace test_general_range_based_for_loop
738   {
740     struct iter
741     {
742       int i;
744       int& operator* ()
745       {
746         return i;
747       }
749       const int& operator* () const
750       {
751         return i;
752       }
754       iter& operator++()
755       {
756         ++i;
757         return *this;
758       }
759     };
761     struct sentinel
762     {
763       int i;
764     };
766     bool operator== (const iter& i, const sentinel& s)
767     {
768       return i.i == s.i;
769     }
771     bool operator!= (const iter& i, const sentinel& s)
772     {
773       return !(i == s);
774     }
776     struct range
777     {
778       iter begin() const
779       {
780         return {0};
781       }
783       sentinel end() const
784       {
785         return {5};
786       }
787     };
789     void f()
790     {
791       range r {};
793       for (auto i : r)
794       {
795         [[maybe_unused]] auto v = i;
796       }
797     }
799   }
801   namespace test_lambda_capture_asterisk_this_by_value
802   {
804     struct t
805     {
806       int i;
807       int foo()
808       {
809         return [*this]()
810         {
811           return i;
812         }();
813       }
814     };
816   }
818   namespace test_enum_class_construction
819   {
821     enum class byte : unsigned char
822     {};
824     byte foo {42};
826   }
828   namespace test_constexpr_if
829   {
831     template <bool cond>
832     int f ()
833     {
834       if constexpr(cond)
835       {
836         return 13;
837       }
838       else
839       {
840         return 42;
841       }
842     }
844   }
846   namespace test_selection_statement_with_initializer
847   {
849     int f()
850     {
851       return 13;
852     }
854     int f2()
855     {
856       if (auto i = f(); i > 0)
857       {
858         return 3;
859       }
861       switch (auto i = f(); i + 4)
862       {
863       case 17:
864         return 2;
866       default:
867         return 1;
868       }
869     }
871   }
873   namespace test_template_argument_deduction_for_class_templates
874   {
876     template <typename T1, typename T2>
877     struct pair
878     {
879       pair (T1 p1, T2 p2)
880         : m1 {p1},
881           m2 {p2}
882       {}
884       T1 m1;
885       T2 m2;
886     };
888     void f()
889     {
890       [[maybe_unused]] auto p = pair{13, 42u};
891     }
893   }
895   namespace test_non_type_auto_template_parameters
896   {
898     template <auto n>
899     struct B
900     {};
902     B<5> b1;
903     B<'a'> b2;
905   }
907   namespace test_structured_bindings
908   {
910     int arr[2] = { 1, 2 };
911     std::pair<int, int> pr = { 1, 2 };
913     auto f1() -> int(&)[2]
914     {
915       return arr;
916     }
918     auto f2() -> std::pair<int, int>&
919     {
920       return pr;
921     }
923     struct S
924     {
925       int x1 : 2;
926       volatile double y1;
927     };
929     S f3()
930     {
931       return {};
932     }
934     auto [ x1, y1 ] = f1();
935     auto& [ xr1, yr1 ] = f1();
936     auto [ x2, y2 ] = f2();
937     auto& [ xr2, yr2 ] = f2();
938     const auto [ x3, y3 ] = f3();
940   }
942   namespace test_exception_spec_type_system
943   {
945     struct Good {};
946     struct Bad {};
948     void g1() noexcept;
949     void g2();
951     template<typename T>
952     Bad
953     f(T*, T*);
955     template<typename T1, typename T2>
956     Good
957     f(T1*, T2*);
959     static_assert (std::is_same_v<Good, decltype(f(g1, g2))>);
961   }
963   namespace test_inline_variables
964   {
966     template<class T> void f(T)
967     {}
969     template<class T> inline T g(T)
970     {
971       return T{};
972     }
974     template<> inline void f<>(int)
975     {}
977     template<> int g<>(int)
978     {
979       return 5;
980     }
982   }
984 }  // namespace cxx17
986 #endif  // __cplusplus < 201703L && !defined _MSC_VER
991 dnl  Tests for new features in C++20
993 m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_20], [[
995 #ifndef __cplusplus
997 #error "This is not a C++ compiler"
999 #elif __cplusplus < 202002L && !defined _MSC_VER
1001 #error "This is not a C++20 compiler"
1003 #else
1005 #include <version>
1007 namespace cxx20
1010 // As C++20 supports feature test macros in the standard, there is no
1011 // immediate need to actually test for feature availability on the
1012 // Autoconf side.
1014 }  // namespace cxx20
1016 #endif  // __cplusplus < 202002L && !defined _MSC_VER