brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.4 KiB · 953b783 Raw
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