102 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9// UNSUPPORTED: c++03, c++11, c++14, c++1710// UNSUPPORTED: no-localization11// UNSUPPORTED: libcpp-has-no-experimental-syncstream12 13// <syncstream>14 15// template <class charT, class traits, class Allocator>16// class basic_osyncstream;17 18// basic_osyncstream& operator=(basic_osyncstream&& rhs);19 20#include <syncstream>21#include <sstream>22#include <cassert>23 24#include "test_macros.h"25#include "test_allocator.h"26 27template <class CharT, bool propagate>28static void test() {29 using Traits = std::char_traits<CharT>;30 using Allocator = std::conditional_t<propagate, other_allocator<CharT>, test_allocator<CharT>>;31 static_assert(std::allocator_traits<Allocator>::propagate_on_container_move_assignment::value == propagate);32 33 using OS = std::basic_osyncstream<CharT, Traits, Allocator>;34 35 std::basic_stringbuf<CharT, Traits, Allocator> base1;36 std::basic_stringbuf<CharT, Traits, Allocator> base2;37 38 {39 OS out1{&base1, Allocator{42}};40 assert(out1.get_wrapped() == &base1);41 42 typename OS::syncbuf_type* sb1 = out1.rdbuf();43 assert(sb1->get_wrapped() == &base1);44 assert(sb1->get_allocator().get_data() == 42);45 46 out1 << CharT('A');47 48 static_assert(!noexcept(out1.operator=(std::move(out1)))); // LWG-386749 OS out2{&base2, Allocator{99}};50 51 out2 << CharT('Z');52 53 // Validate the data is still in the syncbuf and not in the stringbuf.54 assert(base1.str().empty());55 assert(base2.str().empty());56 57 out2 = std::move(out1);58 59 // Since sb2 is overwritten by the move its data should be in its stringbuf.60 assert(base1.str().empty());61 assert(base2.str().size() == 1);62 assert(base2.str()[0] == CharT('Z'));63 64 assert(out2.get_wrapped() == &base1);65 66 typename OS::syncbuf_type* sb2 = out2.rdbuf();67 assert(sb2->get_wrapped() == &base1);68 if constexpr (std::allocator_traits<Allocator>::propagate_on_container_move_assignment::value)69 assert(sb2->get_allocator().get_data() == 42);70 else71 assert(sb2->get_allocator().get_data() == 99);72 73 assert(out1.get_wrapped() == nullptr);74 assert(sb1->get_wrapped() == nullptr);75 76 // The data written to 2 will be stored in sb1. The write happens after the destruction.77 out2 << CharT('B');78 assert(base1.str().empty());79 }80 81 assert(base1.str().size() == 2);82 assert(base1.str()[0] == CharT('A'));83 assert(base1.str()[1] == CharT('B'));84 assert(base2.str().size() == 1);85 assert(base2.str()[0] == CharT('Z'));86}87 88template <class CharT>89static void test() {90 test<CharT, true>();91 test<CharT, false>();92}93 94int main(int, char**) {95 test<char>();96#ifndef TEST_HAS_NO_WIDE_CHARACTERS97 test<wchar_t>();98#endif99 100 return 0;101}102