summaryrefslogtreecommitdiff
path: root/src/inc/clr/stack.h
blob: f9741b274f69509570b0686071ea10285a930ff6 (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
98
99
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
//

//
// This header provides a basic stack implementation

#ifndef _clr_Stack_h_
#define _clr_Stack_h_

namespace clr
{
    //-------------------------------------------------------------------------------------------------
    // A basic stack class.
    //
    template < typename T >
    class Stack
    {
    private:
        //---------------------------------------------------------------------------------------------
        struct Link
        {
            template < typename A1 >
            Link(A1 && a1, Link * next = nullptr)
                : _value(std::forward<A1>(a1))
                , _next(next)
            {}

            T       _value;
            Link *  _next;
        };

    public:
        //---------------------------------------------------------------------------------------------
        // Empty stack constructor.
        Stack()
            : _top(nullptr)
            , _size(0)
        {}

        //---------------------------------------------------------------------------------------------
        // Move constructor.
        Stack(Stack && stack)
            : _top(nullptr)
            , _size(0)
        { *this = std::move(stack); }

        //---------------------------------------------------------------------------------------------
        ~Stack()
        {
            while (!empty())
            {
                pop();
            }
        }

        //---------------------------------------------------------------------------------------------
        // Move assignment.
        Stack& operator=(Stack && stack)
        { std::swap(_top, stack._top); std::swap(_size, stack._size); }

        //---------------------------------------------------------------------------------------------
        bool empty() const
        { return _top == nullptr; }

        //---------------------------------------------------------------------------------------------
        size_t size() const
        { return _size; }

        //---------------------------------------------------------------------------------------------
        T & top()
        { return _top->_value; }

        //---------------------------------------------------------------------------------------------
        T const & top() const
        { return _top->_value; }

        //---------------------------------------------------------------------------------------------
        template < typename A1 > inline
        void push(A1 && value)
        {
            STATIC_CONTRACT_THROWS;
            _top = new Link(std::forward<A1>(value), _top);
            ++_size;
        }

        //---------------------------------------------------------------------------------------------
        void pop()
        { Link * del = _top; _top = _top->_next; --_size; delete del; }

    private:
        //---------------------------------------------------------------------------------------------
        Link * _top;
        size_t _size;
    };
} // namespace clr

#endif // _clr_Stack_h_