ptr_vector.h 3.42 KB
Newer Older
1
// -*- coding:utf-8-with-signature; mode:c++; tab-width:8; -*-
Hisashi Horikawa's avatar
add.  
Hisashi Horikawa committed
2

3
4
#ifndef PTR_VECTOR_H__
#define PTR_VECTOR_H__ 1
Hisashi Horikawa's avatar
add.  
Hisashi Horikawa committed
5
6

#include <vector>
Hisashi Horikawa's avatar
Hisashi Horikawa committed
7
#include <type_traits>
8
9
10
#ifndef NDEBUG
  #include <stdio.h>
#endif
Hisashi Horikawa's avatar
add.  
Hisashi Horikawa committed
11

12
13
14
/**
 * 使い方:
 *     ptr_vector<Foo*> var;
15
 *     var.push_back(new Foo(...));
16
17
 *
 * pop_front() はない.
Hisashi Horikawa's avatar
Hisashi Horikawa committed
18
 * 派生にするのは誤り.
19
20
 */
template <typename T>
Hisashi Horikawa's avatar
Hisashi Horikawa committed
21
class ptr_vector
Hisashi Horikawa's avatar
add.  
Hisashi Horikawa committed
22
{
Hisashi Horikawa's avatar
Hisashi Horikawa committed
23
24
25
26
    static_assert(std::is_pointer<T>::value, "template parameter T must be pointer type");

    typedef std::vector<T> Container;
    Container container;
27
28

public: 
Hisashi Horikawa's avatar
Hisashi Horikawa committed
29
30
31
32
33
    typedef typename Container::iterator        iterator;
    typedef typename Container::const_iterator  const_iterator;
    typedef typename Container::size_type       size_type;
    typedef typename Container::reference       reference;
    typedef typename Container::const_reference const_reference;
34

Hisashi Horikawa's avatar
add.  
Hisashi Horikawa committed
35
    ptr_vector() { }
36
    
Hisashi Horikawa's avatar
add.  
Hisashi Horikawa committed
37
    virtual ~ptr_vector() { clear(); }
38

Hisashi Horikawa's avatar
fix.    
Hisashi Horikawa committed
39
40
    iterator begin() noexcept { return container.begin(); }
    const_iterator begin() const noexcept { return container.begin(); }
Hisashi Horikawa's avatar
Hisashi Horikawa committed
41

Hisashi Horikawa's avatar
fix.    
Hisashi Horikawa committed
42
43
    iterator end() noexcept { return container.end(); }
    const_iterator end() const noexcept { return container.end(); }
Hisashi Horikawa's avatar
Hisashi Horikawa committed
44
45
46
47
48

#if __cplusplus >= 201103L
    const_iterator cbegin() const noexcept {
        return container.cbegin();
    }
Hisashi Horikawa's avatar
fix.    
Hisashi Horikawa committed
49

Hisashi Horikawa's avatar
Hisashi Horikawa committed
50
51
52
53
54
    const_iterator cend() const noexcept {
        return container.cend();
    }
#endif

Hisashi Horikawa's avatar
fix.    
Hisashi Horikawa committed
55
    size_type size() const noexcept {
Hisashi Horikawa's avatar
Hisashi Horikawa committed
56
57
58
        return container.size();
    }

Hisashi Horikawa's avatar
fix.    
Hisashi Horikawa committed
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
    reference at(size_type n) {
        return container.at(n); // throw out_of_range()
    }

    const_reference at(size_type n) const {
        return container.at(n); // throw out_of_range()
    }

    reference operator [] (size_type n) {
        return container.at(n);
    }

    const_reference operator [] (size_type n) const {
        return container.at(n);
    }
    
Hisashi Horikawa's avatar
Hisashi Horikawa committed
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
    reference front() {
        assert( size() > 0 );
        return *container.begin();
    }

    const_reference front() const {
        assert( size() > 0 );
        return *container.cbegin();
    }

    reference back() {
        assert( size() > 0 );
        return *(container.end() - 1);
    }

    const_reference back() const {
        assert( size() > 0 );
        return *(container.cend() - 1);
    }
    
95
    void push_back(const T& v) {
Hisashi Horikawa's avatar
Hisashi Horikawa committed
96
97
#ifndef NDEBUG
        if ( v == nullptr )
98
            printf("warning: add NULL.\n"); // DEBUG
Hisashi Horikawa's avatar
Hisashi Horikawa committed
99
#endif
Hisashi Horikawa's avatar
Hisashi Horikawa committed
100
        container.push_back(v);
101
102
    }

Hisashi Horikawa's avatar
Hisashi Horikawa committed
103
/*
104
105
106
107
108
    void push_front(const T& v) {
        if ( !v )
            printf("warning: add NULL.\n"); // DEBUG
        super::push_front(v);
    }
Hisashi Horikawa's avatar
Hisashi Horikawa committed
109
 */
110
111
112
113
114
115
116
117
118
119

    
    iterator
#if __cplusplus >= 201103L
    erase(const_iterator it)
#else
    erase(iterator it )
#endif
    {
        delete (*it);
Hisashi Horikawa's avatar
Hisashi Horikawa committed
120
        return container.erase(it);
121
122
    }

Hisashi Horikawa's avatar
fix.    
Hisashi Horikawa committed
123
    // コンテナからは削除する
124
125
    T detach(iterator it) {
        T r = *it;
Hisashi Horikawa's avatar
Hisashi Horikawa committed
126
        container.erase(it);
127
128
        return r;
    }
129
130
131
132
133
134
135
136
137
138
139
    
    iterator
#if __cplusplus >= 201103L
    erase(const_iterator __first, const_iterator __last)
#else
    erase(iterator __first, iterator __last)
#endif        
    {
        const_iterator i;
        for (i = __first; i != __last; i++)
            delete *i;
Hisashi Horikawa's avatar
Hisashi Horikawa committed
140
        return container.erase(__first, __last);
141
    }
Hisashi Horikawa's avatar
add.  
Hisashi Horikawa committed
142
143
    
    void clear() {
144
        iterator it;
Hisashi Horikawa's avatar
Hisashi Horikawa committed
145
        for (it = begin(); it != end(); it++)
146
            delete *it;
Hisashi Horikawa's avatar
Hisashi Horikawa committed
147
        container.clear();
Hisashi Horikawa's avatar
add.  
Hisashi Horikawa committed
148
149
    }
};
Hisashi Horikawa's avatar
fix.    
Hisashi Horikawa committed
150

151
152
153
154
155
156
157
158

#endif // !PTR_VECTOR_H__

// Local variables:
// tab-width: 4
// c-basic-offset: 4
// indent-tabs-mode: nil
// End: