| 1 | //---------------------------------------------------------------------------- |
| 2 | /// @file stack_cnc.hpp |
| 3 | /// @brief This file contains the implementation concurrent stack |
| 4 | /// |
| 5 | /// @author Copyright (c) 2010 2015 Francisco José Tapia (fjtapia@gmail.com )\n |
| 6 | /// Distributed under the Boost Software License, Version 1.0.\n |
| 7 | /// ( See accompanyingfile LICENSE_1_0.txt or copy at |
| 8 | /// http://www.boost.org/LICENSE_1_0.txt ) |
| 9 | /// @version 0.1 |
| 10 | /// |
| 11 | /// @remarks |
| 12 | //----------------------------------------------------------------------------- |
| 13 | #ifndef __BOOST_SORT_PARALLEL_DETAIL_UTIL_STACK_CNC_HPP |
| 14 | #define __BOOST_SORT_PARALLEL_DETAIL_UTIL_STACK_CNC_HPP |
| 15 | |
| 16 | #include <ciso646> |
| 17 | #include <vector> |
| 18 | #include <boost/sort/common/spinlock.hpp> |
| 19 | |
| 20 | |
| 21 | namespace boost |
| 22 | { |
| 23 | namespace sort |
| 24 | { |
| 25 | namespace common |
| 26 | { |
| 27 | |
| 28 | // |
| 29 | //########################################################################### |
| 30 | // ## |
| 31 | // ################################################################ ## |
| 32 | // # # ## |
| 33 | // # C L A S S # ## |
| 34 | // # S T A C K _ C N C # ## |
| 35 | // # # ## |
| 36 | // ################################################################ ## |
| 37 | // ## |
| 38 | //########################################################################### |
| 39 | // |
| 40 | //--------------------------------------------------------------------------- |
| 41 | /// @class stack_cnc |
| 42 | /// @brief This class is a concurrent stack controled by a spin_lock |
| 43 | /// @remarks |
| 44 | //--------------------------------------------------------------------------- |
| 45 | template<typename T, typename Allocator = std::allocator<T> > |
| 46 | class stack_cnc |
| 47 | { |
| 48 | public: |
| 49 | //------------------------------------------------------------------------ |
| 50 | // D E F I N I T I O N S |
| 51 | //------------------------------------------------------------------------ |
| 52 | typedef std::vector<T, Allocator> vector_t; |
| 53 | typedef typename vector_t::size_type size_type; |
| 54 | typedef typename vector_t::difference_type difference_type; |
| 55 | typedef typename vector_t::value_type value_type; |
| 56 | typedef typename vector_t::pointer pointer; |
| 57 | typedef typename vector_t::const_pointer const_pointer; |
| 58 | typedef typename vector_t::reference reference; |
| 59 | typedef typename vector_t::const_reference const_reference; |
| 60 | typedef typename vector_t::allocator_type allocator_type; |
| 61 | typedef Allocator alloc_t; |
| 62 | |
| 63 | protected: |
| 64 | //------------------------------------------------------------------------- |
| 65 | // INTERNAL VARIABLES |
| 66 | //------------------------------------------------------------------------- |
| 67 | vector_t v_t; |
| 68 | mutable spinlock_t spl; |
| 69 | |
| 70 | public: |
| 71 | // |
| 72 | //------------------------------------------------------------------------- |
| 73 | // function : stack_cnc |
| 74 | /// @brief constructor |
| 75 | //------------------------------------------------------------------------- |
| 76 | explicit stack_cnc(void): v_t() { }; |
| 77 | |
| 78 | // |
| 79 | //------------------------------------------------------------------------- |
| 80 | // function : stack_cnc |
| 81 | /// @brief Move constructor |
| 82 | //------------------------------------------------------------------------- |
| 83 | stack_cnc(stack_cnc &&) = delete; |
| 84 | // |
| 85 | //------------------------------------------------------------------------- |
| 86 | // function : ~stack_cnc |
| 87 | /// @brief Destructor |
| 88 | //------------------------------------------------------------------------- |
| 89 | virtual ~stack_cnc(void) { v_t.clear(); }; |
| 90 | |
| 91 | //------------------------------------------------------------------------- |
| 92 | // function : emplace_back |
| 93 | /// @brief Insert one element in the back of the container |
| 94 | /// @param args : group of arguments for to build the object to insert. Can |
| 95 | /// be values, references or rvalues |
| 96 | //------------------------------------------------------------------------- |
| 97 | template<class ... Args> |
| 98 | void emplace_back(Args &&... args) |
| 99 | { |
| 100 | std::lock_guard < spinlock_t > guard(spl); |
| 101 | v_t.emplace_back(std::forward< Args > (args)...); |
| 102 | } |
| 103 | |
| 104 | // |
| 105 | //------------------------------------------------------------------------- |
| 106 | // function :pop_move_back |
| 107 | /// @brief if exist, move the last element to P, and delete it |
| 108 | /// @param P : reference to a variable where move the element |
| 109 | /// @return true - Element moved and deleted |
| 110 | /// false - Empty stack_cnc |
| 111 | //------------------------------------------------------------------------- |
| 112 | bool pop_move_back(value_type &P) |
| 113 | { |
| 114 | std::lock_guard < spinlock_t > S(spl); |
| 115 | if (v_t.size() == 0) return false; |
| 116 | P = std::move(v_t.back()); |
| 117 | v_t.pop_back(); |
| 118 | return true; |
| 119 | } |
| 120 | //------------------------------------------------------------------------- |
| 121 | // function : push_back |
| 122 | /// @brief Insert one vector at the end of the container |
| 123 | /// @param v_other : vector to insert |
| 124 | /// @return reference to the stack_cnc after the insertion |
| 125 | //------------------------------------------------------------------------- |
| 126 | template<class Allocator2> |
| 127 | stack_cnc &push_back(const std::vector<value_type, Allocator2> &v_other) |
| 128 | { |
| 129 | std::lock_guard < spinlock_t > guard(spl); |
| 130 | for (size_type i = 0; i < v_other.size(); ++i) |
| 131 | { |
| 132 | v_t.push_back(v_other[i]); |
| 133 | } |
| 134 | return *this; |
| 135 | } |
| 136 | }; |
| 137 | // end class stack_cnc |
| 138 | |
| 139 | //*************************************************************************** |
| 140 | };// end namespace common |
| 141 | };// end namespace sort |
| 142 | };// end namespace boost |
| 143 | //*************************************************************************** |
| 144 | #endif |
| 145 | |