summaryrefslogtreecommitdiffstats
path: root/test/libcxx/debug/containers/db_string.pass.cpp
blob: 8d1a622b4ffe6ed539957f5a0a546a84bf38a64d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
//===----------------------------------------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++98, c++03, c++11, c++14
// UNSUPPORTED: libcpp-no-exceptions, libcpp-no-if-constexpr
// MODULES_DEFINES: _LIBCPP_DEBUG=1
// MODULES_DEFINES: _LIBCPP_DEBUG_USE_EXCEPTIONS

// test container debugging

#define _LIBCPP_DEBUG 1
#define _LIBCPP_DEBUG_USE_EXCEPTIONS
#include <string>
#include <vector>

#include "test_macros.h"
#include "debug_mode_helper.h"

using namespace IteratorDebugChecks;

typedef std::basic_string<char, std::char_traits<char>, test_allocator<char>>  StringType;

template <class Container = StringType, ContainerType CT = CT_String>
struct StringContainerChecks : BasicContainerChecks<Container, CT> {
  using Base = BasicContainerChecks<Container, CT_String>;
  using value_type = typename Container::value_type;
  using allocator_type = typename Container::allocator_type;
  using iterator = typename Container::iterator;
  using const_iterator = typename Container::const_iterator;

  using Base::makeContainer;
  using Base::makeValueType;

public:
  static void run() {
    Base::run_iterator_tests();
    Base::run_allocator_aware_tests();
    try {
      for (int N : {3, 128}) {
        FrontOnEmptyContainer(N);
        BackOnEmptyContainer(N);
        PopBack(N);
      }
    } catch (...) {
      assert(false && "uncaught debug exception");
    }
  }

private:
  static void BackOnEmptyContainer(int N) {
    CHECKPOINT("testing back on empty");
    Container C = makeContainer(N);
    Container const& CC = C;
    iterator it = --C.end();
    (void)C.back();
    (void)CC.back();
    C.pop_back();
    CHECK_DEBUG_THROWS( C.erase(it) );
    C.clear();
    CHECK_DEBUG_THROWS( C.back() );
    CHECK_DEBUG_THROWS( CC.back() );
  }

  static void FrontOnEmptyContainer(int N) {
    CHECKPOINT("testing front on empty");
    Container C = makeContainer(N);
    Container const& CC = C;
    (void)C.front();
    (void)CC.front();
    C.clear();
    CHECK_DEBUG_THROWS( C.front() );
    CHECK_DEBUG_THROWS( CC.front() );
  }

  static void PopBack(int N) {
    CHECKPOINT("testing pop_back() invalidation");
    Container C1 = makeContainer(N);
    iterator it1 = C1.end();
    --it1;
    C1.pop_back();
    CHECK_DEBUG_THROWS( C1.erase(it1) );
    C1.erase(C1.begin(), C1.end());
    assert(C1.size() == 0);
    CHECK_DEBUG_THROWS( C1.pop_back() );
  }
};

int main()
{
  StringContainerChecks<>::run();
}