First Commit
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
Configuration tests
|
||||
===================
|
||||
|
||||
Libpqxx comes with support for different build systems: the GNU autotools,
|
||||
CMake, Visual Studio's "nmake", and raw GNU "make" on Windows.
|
||||
|
||||
For several of these build systems, we need to test things like "does this
|
||||
compiler environment support `std::to_chars` for floating-point types?"
|
||||
|
||||
We test these things by trying to compile a particular snippet of code, and
|
||||
seeing whether that succeeds.
|
||||
|
||||
To avoid duplicating those snippets for multiple build systems, we put them
|
||||
here. Both the autotools configuration and the CMake configuration can refer to
|
||||
them that way.
|
||||
|
||||
It took a bit of nasty magic to read a C++ source file into m4 and treat it as
|
||||
a string literal, without macro expansion. There is every chance that I missed
|
||||
something, so be prepared for tests failing for unexpected reasons! Some C++
|
||||
syntax may end up having an unforeseen meaning in m4, and screw up the handling
|
||||
of the code snippet. Re-configure, and read your logs carefully after editing
|
||||
these snippets.
|
||||
@@ -0,0 +1,16 @@
|
||||
// Test for std::to_string/std::from_string for floating-point types.
|
||||
#include <charconv>
|
||||
#include <iterator>
|
||||
|
||||
int main()
|
||||
{
|
||||
char z[100];
|
||||
auto rt = std::to_chars(std::begin(z), std::end(z), 3.14159L);
|
||||
if (rt.ec != std::errc{})
|
||||
return 1;
|
||||
long double n;
|
||||
auto rf = std::from_chars(std::cbegin(z), std::cend(z), n);
|
||||
if (rf.ec != std::errc{})
|
||||
return 2;
|
||||
return (n > 3 and n < 4) ? 0 : 1;
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
// Test for std::to_string/std::from_string for integral types.
|
||||
#include <charconv>
|
||||
#include <iterator>
|
||||
|
||||
int main()
|
||||
{
|
||||
char z[100];
|
||||
auto rt = std::to_chars(std::begin(z), std::end(z), 9ULL);
|
||||
if (rt.ec != std::errc{})
|
||||
return 1;
|
||||
unsigned long long n;
|
||||
auto rf = std::from_chars(std::cbegin(z), std::cend(z), n);
|
||||
if (rf.ec != std::errc{})
|
||||
return 2;
|
||||
return (n == 9ULL) ? 0 : 1;
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
// Test for C++20 std::cmp_greater etc. support.
|
||||
#include <utility>
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
return std::cmp_greater(-1, 2u) && std::cmp_less_equal(3, 0);
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
// Test for concepts support. Not just the language feature; also headers.
|
||||
#include <iostream>
|
||||
#include <ranges>
|
||||
#include <vector>
|
||||
|
||||
|
||||
template<typename T>
|
||||
concept Foo = std::ranges::input_range<T>;
|
||||
|
||||
|
||||
template<Foo F> auto foo(F const &r)
|
||||
{
|
||||
return std::distance(std::begin(r), std::end(r));
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
std::vector<int> const v{1, 2, 3};
|
||||
std::cout << foo(v) << '\n';
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
// Test for cross-vendor C++ ABI's __cxa_demangle function.
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <stdexcept>
|
||||
#include <typeinfo>
|
||||
|
||||
#include <cxxabi.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
int status = 0;
|
||||
char *name =
|
||||
abi::__cxa_demangle(typeid(10).name(), nullptr, nullptr, &status);
|
||||
if (status != 0)
|
||||
throw std::runtime_error("Demangle failed!");
|
||||
int result = std::strcmp(name, "int");
|
||||
std::free(name);
|
||||
return result;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
// Check for working std::filesystem support.
|
||||
#include <filesystem>
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
// Apparently some versions of MinGW lack this comparison operator.
|
||||
return std::filesystem::path{} != std::filesystem::path{};
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// Test for gcc-style "pure" attribute.
|
||||
int __attribute__((pure)) f()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
return f();
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
// Test for gcc-style "visibility" attribute.
|
||||
struct __attribute__((visibility("hidden"))) D
|
||||
{
|
||||
D() {}
|
||||
int f() { return 0; }
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
D d;
|
||||
return d.f();
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
// Test for C++20 [[likely]] and [[unlikely]] attributes.
|
||||
|
||||
int main(int argc, char **)
|
||||
{
|
||||
#if __cplusplus < 202002L
|
||||
deliberately_fail(because, older, C++, standard);
|
||||
#endif
|
||||
|
||||
int x = 0;
|
||||
if (argc == 1) [[likely]]
|
||||
x = 0;
|
||||
else
|
||||
x = 1;
|
||||
return x;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
// Test for multidimensional subscript operator support.
|
||||
// Proposed for C++23: P2128R6.
|
||||
struct table
|
||||
{
|
||||
int width = 100;
|
||||
|
||||
int operator[](int x, int y) const { return x + width * y; }
|
||||
};
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
return table{}[0, 0];
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
// Check whether we need to link to the stdc++fs library.
|
||||
//
|
||||
// We assume that the presence of the <filesystem> header means that we have
|
||||
// support for the basics of std::filesystem. This check will succeed if
|
||||
// either there is no <filesystem> header, or there is one and it works without
|
||||
// any special options. If the link fails, we assume that -lstdc++fs will fix
|
||||
// it for us.
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#if __has_include(<filesystem>)
|
||||
# include <filesystem>
|
||||
#endif
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
#if __has_include(<filesystem>)
|
||||
std::cout << std::filesystem::path{"foo.bar"}.c_str() << '\n';
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
// Test for poll().
|
||||
#include <poll.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
return poll(nullptr, 0, 0);
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
// Test for std::this_thread::sleep_for().
|
||||
/* For some reason MinGW's <thread> header seems to be broken.
|
||||
*
|
||||
* But it gets worse. It looks as if we can include <thread> without problems
|
||||
* in this configuration test. Why does it break when MinGW users try to build
|
||||
* the library, but succeed when we try it here?
|
||||
*
|
||||
* To try and get close to the situation in the library code itself, we try
|
||||
* including some standard headers that we don't strictly need here.
|
||||
*/
|
||||
|
||||
#if __has_include(<ciso646>)
|
||||
# include <ciso646>
|
||||
#endif
|
||||
|
||||
#include <cerrno>
|
||||
#include <cmath>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <new>
|
||||
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
|
||||
int main()
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::microseconds{10u});
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
// Test for std::span.
|
||||
#include <span>
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
std::span<char *> args{argv, static_cast<std::size_t>(argc)};
|
||||
return static_cast<int>(std::size(args) - 1u);
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
// Check for strerror_r.
|
||||
// It can be either the POSIX version (which returns int) or the GNU version
|
||||
// (which returns char *).
|
||||
|
||||
#include <cstring>
|
||||
#include <type_traits>
|
||||
|
||||
int main()
|
||||
{
|
||||
char buffer[200];
|
||||
auto res{strerror_r(1, buffer, 200)};
|
||||
// Sidestep type differences. We don't really care what the value is.
|
||||
return not not res;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
// Test for strerror_s, as defined in Windows and C11.
|
||||
// Presumably this'll be part of the C++ standard some day.
|
||||
|
||||
#include <cstring>
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace std;
|
||||
char buf[200];
|
||||
return strerror_s(buf, 200, 1);
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
// Test for std::to_string/std::from_string for floating-point types.
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
int main(int argc, char **)
|
||||
{
|
||||
#if defined(__MINGW32__) && defined(__GNUC__)
|
||||
# if __GNUC__ < 11 || ((__GNUC__ == 11) && (__GNU_MINOR__ == 0))
|
||||
# error "On MinGW before gcc 11.1, thread_local breaks at run time."
|
||||
# endif
|
||||
#endif
|
||||
thread_local std::stringstream s;
|
||||
s << argc;
|
||||
std::cout << s.str();
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
// Test for std::chrono::year_month_day etc.
|
||||
#include <chrono>
|
||||
|
||||
int main()
|
||||
{
|
||||
return int(std::chrono::year{1});
|
||||
}
|
||||
Reference in New Issue
Block a user