//===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // basic_streambuf* setbuf(char_type* s, streamsize n) override; // In C++23 and later, this test requires support for P2467R1 in the dylib (a3f17ba3febbd546f2342ffc780ac93b694fdc8d) // XFAIL: (!c++03 && !c++11 && !c++14 && !c++17 && !c++20) && using-built-library-before-llvm-18 #include #include #include #include "test_macros.h" template static std::size_t file_size(const char* filename) { FILE* f = std::fopen(filename, "rb"); std::fseek(f, 0, SEEK_END); long result = std::ftell(f); std::fclose(f); return result; } // Helper class to expose some protected std::basic_filebuf members. template struct filebuf : public std::basic_filebuf { CharT* base() { return this->pbase(); } CharT* ptr() { return this->pptr(); } }; template static void buffered_request() { filebuf buffer; CharT b[10] = {0}; assert(buffer.pubsetbuf(b, 10) == &buffer); buffer.open("test.dat", std::ios_base::out); buffer.sputc(CharT('a')); assert(b[0] == 'a'); buffer.close(); assert(file_size("test.dat") == 1); } template static void unbuffered_request_before_open() { filebuf buffer; assert(buffer.pubsetbuf(nullptr, 0) == &buffer); assert(buffer.base() == nullptr); assert(buffer.ptr() == nullptr); buffer.open("test.dat", std::ios_base::out); assert(buffer.base() == nullptr); assert(buffer.ptr() == nullptr); buffer.sputc(CharT('a')); assert(buffer.base() == nullptr); assert(buffer.ptr() == nullptr); assert(file_size("test.dat") == 1); } template static void unbuffered_request_after_open() { filebuf buffer; buffer.open("test.dat", std::ios_base::out); assert(buffer.pubsetbuf(nullptr, 0) == &buffer); assert(buffer.base() == nullptr); assert(buffer.ptr() == nullptr); buffer.sputc(CharT('a')); assert(buffer.base() == nullptr); assert(buffer.ptr() == nullptr); assert(file_size("test.dat") == 1); } template static void unbuffered_request_after_open_ate() { filebuf buffer; buffer.open("test.dat", std::ios_base::out | std::ios_base::ate); assert(buffer.pubsetbuf(nullptr, 0) == &buffer); buffer.sputc(CharT('a')); assert(file_size("test.dat") <= 1); // on libc++ buffering is used by default. LIBCPP_ASSERT(file_size("test.dat") == 0); buffer.close(); assert(file_size("test.dat") == 1); } template static void test() { buffered_request(); unbuffered_request_before_open(); unbuffered_request_after_open(); unbuffered_request_after_open_ate(); } int main(int, char**) { test(); #ifndef TEST_HAS_NO_WIDE_CHARACTERS test(); #endif return 0; }