1 //===----------------------------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef TEST_STD_INPUT_OUTPUT_FILE_STREAMS_FSTREAMS_TEST_HELPERS_H 10 #define TEST_STD_INPUT_OUTPUT_FILE_STREAMS_FSTREAMS_TEST_HELPERS_H 11 12 #include <cassert> 13 #include <cerrno> 14 #include <concepts> 15 #include <cstdio> 16 #include <fstream> 17 #include <filesystem> 18 #include <type_traits> 19 #include <utility> 20 21 #if defined(_WIN32) 22 # include <io.h> 23 # include <windows.h> 24 #else 25 # include <fcntl.h> 26 #endif 27 28 #include "platform_support.h" 29 #include "types.h" 30 31 #if TEST_STD_VER >= 26 32 33 inline bool is_handle_valid(NativeHandleT handle) { 34 # if defined(_WIN32) 35 BY_HANDLE_FILE_INFORMATION fileInformation; 36 return GetFileInformationByHandle(handle, &fileInformation); 37 # elif __has_include(<unistd.h>) // POSIX 38 return fcntl(handle, F_GETFL) != -1 || errno != EBADF; 39 # else 40 # error "Provide a native file handle!" 41 # endif 42 } 43 44 template <typename CharT, typename StreamT> 45 inline void test_native_handle() { 46 static_assert( 47 std::is_same_v<typename std::basic_filebuf<CharT>::native_handle_type, typename StreamT::native_handle_type>); 48 49 StreamT f; 50 std::filesystem::path p = get_temp_file_name(); 51 52 // non-const 53 { 54 f.open(p); 55 std::same_as<NativeHandleT> decltype(auto) handle = f.native_handle(); 56 assert(is_handle_valid(handle)); 57 assert(f.rdbuf()->native_handle() == handle); 58 assert(std::as_const(f).rdbuf()->native_handle() == handle); 59 f.close(); 60 assert(!is_handle_valid(handle)); 61 static_assert(noexcept(f.native_handle())); 62 } 63 // const 64 { 65 f.open(p); 66 std::same_as<NativeHandleT> decltype(auto) const_handle = std::as_const(f).native_handle(); 67 assert(is_handle_valid(const_handle)); 68 assert(f.rdbuf()->native_handle() == const_handle); 69 assert(std::as_const(f).rdbuf()->native_handle() == const_handle); 70 f.close(); 71 assert(!is_handle_valid(const_handle)); 72 static_assert(noexcept(std::as_const(f).native_handle())); 73 } 74 } 75 76 template <typename StreamT> 77 inline void test_native_handle_type() { 78 static_assert(std::is_trivially_copyable_v<typename StreamT::native_handle_type>); 79 static_assert(std::semiregular<typename StreamT::native_handle_type>); 80 static_assert(std::is_same_v<typename StreamT::native_handle_type, NativeHandleT>); 81 } 82 83 #endif // #if TEST_STD_VER >= 26 84 85 #endif // TEST_STD_INPUT_OUTPUT_FILE_STREAMS_FSTREAMS_TEST_HELPERS_H 86