summaryrefslogtreecommitdiff
path: root/boost/sort/common/stack_cnc.hpp
blob: d4d6e53b25e11dc9008c7d965d1959594d6d743a (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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
//----------------------------------------------------------------------------
/// @file   stack_cnc.hpp
/// @brief  This file contains the implementation concurrent stack
///
/// @author Copyright (c) 2010 2015 Francisco José Tapia (fjtapia@gmail.com )\n
///         Distributed under the Boost Software License, Version 1.0.\n
///         ( See accompanyingfile LICENSE_1_0.txt or copy at
///           http://www.boost.org/LICENSE_1_0.txt  )
/// @version 0.1
///
/// @remarks
//-----------------------------------------------------------------------------
#ifndef __BOOST_SORT_PARALLEL_DETAIL_UTIL_STACK_CNC_HPP
#define __BOOST_SORT_PARALLEL_DETAIL_UTIL_STACK_CNC_HPP

#include <boost/sort/common/spinlock.hpp>
#include <vector>

namespace boost
{
namespace sort
{
namespace common
{

//
//###########################################################################
//                                                                         ##
//    ################################################################     ##
//    #                                                              #     ##
//    #                      C L A S S                               #     ##
//    #                   S T A C K _ C N C                          #     ##
//    #                                                              #     ##
//    ################################################################     ##
//                                                                         ##
//###########################################################################
//
//---------------------------------------------------------------------------
/// @class  stack_cnc
/// @brief This class is a concurrent stack controled by a spin_lock
/// @remarks
//---------------------------------------------------------------------------
template<typename T, typename Allocator = std::allocator<T> >
class stack_cnc
{
public:
    //------------------------------------------------------------------------
    //                     D E F I N I T I O N S
    //------------------------------------------------------------------------
    typedef std::vector<T, Allocator> vector_t;
    typedef typename vector_t::size_type size_type;
    typedef typename vector_t::difference_type difference_type;
    typedef typename vector_t::value_type value_type;
    typedef typename vector_t::pointer pointer;
    typedef typename vector_t::const_pointer const_pointer;
    typedef typename vector_t::reference reference;
    typedef typename vector_t::const_reference const_reference;
    typedef typename vector_t::allocator_type allocator_type;
    typedef Allocator alloc_t;

protected:
    //-------------------------------------------------------------------------
    //                   INTERNAL VARIABLES
    //-------------------------------------------------------------------------
    vector_t v_t;
    mutable spinlock_t spl;

public:
    //
    //-------------------------------------------------------------------------
    //  function : stack_cnc
    /// @brief  constructor
    //-------------------------------------------------------------------------
    explicit stack_cnc(void): v_t() { };

    //
    //-------------------------------------------------------------------------
    //  function : stack_cnc
    /// @brief  Move constructor
    //-------------------------------------------------------------------------
    stack_cnc(stack_cnc &&) = delete;
    //
    //-------------------------------------------------------------------------
    //  function : ~stack_cnc
    /// @brief  Destructor
    //-------------------------------------------------------------------------
    virtual ~stack_cnc(void) { v_t.clear(); };

    //-------------------------------------------------------------------------
    //  function : emplace_back
    /// @brief Insert one element in the back of the container
    /// @param args : group of arguments for to build the object to insert. Can
    ///               be values, references or rvalues
    //-------------------------------------------------------------------------
    template<class ... Args>
    void emplace_back(Args &&... args)
    {
        std::lock_guard < spinlock_t > guard(spl);
        v_t.emplace_back(std::forward< Args > (args)...);
    };

    //
    //-------------------------------------------------------------------------
    //  function :pop_move_back
    /// @brief if exist, move the last element to P, and delete it
    /// @param P : reference to a variable where move the element
    /// @return  true  - Element moved and deleted
    ///          false - Empty stack_cnc
    //-------------------------------------------------------------------------
    bool pop_move_back(value_type &P)
    {
        std::lock_guard < spinlock_t > S(spl);
        if (v_t.size() == 0) return false;
        P = std::move(v_t.back());
        v_t.pop_back();
        return true;
    };
    //-------------------------------------------------------------------------
    //  function : push_back
    /// @brief Insert one vector at the end of the container
    /// @param v_other : vector to insert
    /// @return reference to the stack_cnc after the insertion
    //-------------------------------------------------------------------------
    template<class Allocator2>
    stack_cnc &push_back(const std::vector<value_type, Allocator2> &v_other)
    {
        std::lock_guard < spinlock_t > guard(spl);
        for (size_type i = 0; i < v_other.size(); ++i)
        {
            v_t.push_back(v_other[i]);
        }
        return *this;
    };
};
// end class stack_cnc

//***************************************************************************
};// end namespace common
};// end namespace sort
};// end namespace boost
//***************************************************************************
#endif