152 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_syncbuf;17 18// Tests the inherited function using a custom allocator.19//20// int_type basic_streambuf<charT, traits>::sputc(char_type c);21//22// This test also validates the observable behaviour after move assignment and23// construction. This test uses a small so the underlying string is in short24// mode.25 26#include <array>27#include <syncstream>28#include <cassert>29#include <sstream>30 31#include "test_macros.h"32#include "test_allocator.h"33 34template <class CharT>35void test() {36 std::array< CharT, 17> input{37 CharT('a'),38 CharT('1'),39 CharT('+'),40 CharT('A'),41 CharT('g'),42 CharT('0'),43 CharT('@'),44 CharT('Z'),45 CharT('q'),46 CharT('8'),47 CharT('#'),48 CharT('D'),49 CharT('t'),50 CharT('9'),51 CharT('$'),52 CharT('A'),53 CharT(' ')};54 using SyncBuf = std::basic_syncbuf<CharT, std::char_traits<CharT>, test_allocator<CharT>>;55 56 { // Normal57 std::basic_string<CharT> expected;58 std::basic_stringbuf<CharT> buf;59 test_allocator_statistics stats;60 test_allocator<CharT> allocator{&stats};61 62 {63 SyncBuf sync_buf{&buf, allocator};64 for (int i = 0; i < 1024; ++i) {65 CharT c = input[i % input.size()];66 expected.push_back(c);67 typename SyncBuf::int_type ret = sync_buf.sputc(c);68 assert(ret == typename SyncBuf::int_type(c));69 }70 // The synchronization happens upon destruction of sync_buf.71 assert(buf.str().empty());72 assert(stats.allocated_size >= 1024);73 }74 assert(buf.str() == expected);75 assert(stats.allocated_size == 0);76 }77 { // Move construction78 std::basic_stringbuf<CharT> buf;79 test_allocator_statistics stats;80 test_allocator<CharT> allocator{&stats};81 82 {83 SyncBuf sync_buf{&buf, allocator};84 CharT c = CharT('4');85 typename SyncBuf::int_type ret = sync_buf.sputc(c);86 assert(ret == typename SyncBuf::int_type(c));87 88 {89 c = CharT('2');90 91 SyncBuf new_sync_buf{std::move(sync_buf)};92 ret = new_sync_buf.sputc(c);93 assert(ret == typename SyncBuf::int_type(c));94 95 // The synchronization happens upon destruction of new_sync_buf.96 assert(buf.str().empty());97 assert(stats.allocated_size >= 2);98 }99 assert(buf.str().size() == 2);100 assert(buf.str()[0] == CharT('4'));101 assert(buf.str()[1] == CharT('2'));102 assert(stats.allocated_size == 0);103 }104 assert(buf.str().size() == 2);105 assert(buf.str()[0] == CharT('4'));106 assert(buf.str()[1] == CharT('2'));107 assert(stats.allocated_size == 0);108 }109 { // Move assignment non-propagating allocator110 std::basic_stringbuf<CharT> buf;111 test_allocator_statistics stats;112 test_allocator<CharT> allocator{&stats};113 static_assert(!std::allocator_traits<test_allocator<CharT>>::propagate_on_container_move_assignment::value);114 115 {116 SyncBuf sync_buf{&buf, allocator};117 CharT c = CharT('4');118 typename SyncBuf::int_type ret = sync_buf.sputc(c);119 assert(ret == typename SyncBuf::int_type(c));120 121 {122 c = CharT('2');123 124 SyncBuf new_sync_buf;125 test_allocator<CharT> a = new_sync_buf.get_allocator();126 new_sync_buf = std::move(sync_buf);127 assert(new_sync_buf.get_allocator() == a);128 129 ret = new_sync_buf.sputc(c);130 assert(ret == typename SyncBuf::int_type(c));131 132 // The synchronization happens upon destruction of new_sync_buf.133 assert(buf.str().empty());134 }135 assert(buf.str().size() == 2);136 assert(buf.str()[0] == CharT('4'));137 assert(buf.str()[1] == CharT('2'));138 }139 assert(buf.str().size() == 2);140 assert(buf.str()[0] == CharT('4'));141 assert(buf.str()[1] == CharT('2'));142 }143}144 145int main(int, char**) {146 test<char>();147#ifndef TEST_HAS_NO_WIDE_CHARACTERS148 test<wchar_t>();149#endif150 return 0;151}152