Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:51:46

0001 //----------------------------------------------------------------------------
0002 /// @file   deque_cnc.hpp
0003 /// @brief  This file contains the implementation of the several types of
0004 ///         recursive fastmutex for read and write
0005 ///
0006 /// @author Copyright (c) 2010 2015 Francisco José Tapia (fjtapia@gmail.com )\n
0007 ///         Distributed under the Boost Software License, Version 1.0.\n
0008 ///         ( See accompanyingfile LICENSE_1_0.txt or copy at
0009 ///           http://www.boost.org/LICENSE_1_0.txt  )
0010 /// @version 0.1
0011 ///
0012 /// @remarks
0013 //-----------------------------------------------------------------------------
0014 #ifndef __TOOLS_DEQUE_CNC_HPP
0015 #define __TOOLS_DEQUE_CNC_HPP
0016 
0017 #include <ciso646>
0018 #include <vector>
0019 #include <deque>
0020 #include <boost/sort/common/spinlock.hpp>
0021 
0022 namespace boost
0023 {
0024 namespace sort
0025 {
0026 namespace common
0027 {
0028 
0029 //###########################################################################
0030 //                                                                         ##
0031 //    ################################################################     ##
0032 //    #                                                              #     ##
0033 //    #                      C L A S S                               #     ##
0034 //    #                   S T A C K _ C N C                          #     ##
0035 //    #                                                              #     ##
0036 //    ################################################################     ##
0037 //                                                                         ##
0038 //###########################################################################
0039 //
0040 //---------------------------------------------------------------------------
0041 /// @class  deque_cnc
0042 /// @brief This class is a concurrent stack controled by a spin_lock
0043 /// @remarks
0044 //---------------------------------------------------------------------------
0045 template<typename T, typename Allocator = std::allocator<T> >
0046 class deque_cnc
0047 {
0048 public:
0049     //-----------------------------------------------------------------------
0050     //                     D E F I N I T I O N S
0051     //-----------------------------------------------------------------------
0052     typedef std::deque<T, Allocator>                deque_t;
0053     typedef typename deque_t::size_type             size_type;
0054     typedef typename deque_t::difference_type       difference_type;
0055     typedef typename deque_t::value_type            value_type;
0056     typedef typename deque_t::pointer               pointer;
0057     typedef typename deque_t::const_pointer         const_pointer;
0058     typedef typename deque_t::reference             reference;
0059     typedef typename deque_t::const_reference       const_reference;
0060     typedef typename deque_t::allocator_type        allocator_type;
0061 
0062 protected:
0063     //------------------------------------------------------------------------
0064     //                     VARIABLES
0065     //------------------------------------------------------------------------
0066     deque_t dq;
0067     mutable spinlock_t spl;
0068 
0069 public:
0070     //
0071     //-----------------------------------------------------------------------
0072     //  C O N S T R U C T O R S     A N D    D E S T R U C T O R
0073     //-----------------------------------------------------------------------
0074     //
0075     //-----------------------------------------------------------------------
0076     //  function : deque_cnc
0077     /// @brief  constructor
0078     //----------------------------------------------------------------------
0079     explicit inline deque_cnc(void): dq() { };
0080 //
0081     //----------------------------------------------------------------------
0082     //  function : deque_cnc
0083     /// @brief  constructor
0084     /// @param [in] ALLC : Allocator
0085     //----------------------------------------------------------------------
0086     explicit inline deque_cnc(const Allocator &ALLC): dq(ALLC){ };
0087     //
0088     //----------------------------------------------------------------------
0089     //  function : ~deque_cnc
0090     /// @brief  Destructor
0091     //----------------------------------------------------------------------
0092     virtual ~deque_cnc(void){ dq.clear(); };
0093     //
0094     //----------------------------------------------------------------------
0095     //  function : clear
0096     /// @brief Delete all the elements of the deque_cnc.
0097     //----------------------------------------------------------------------
0098     void clear(void)
0099     {
0100         std::lock_guard < spinlock_t > S(spl);
0101         dq.clear();
0102     };
0103     //
0104     //------------------------------------------------------------------------
0105     //  function : swap
0106     /// @brief swap the data between the two deque_cnc
0107     /// @param [in] A : deque_cnc to swap
0108     /// @return none
0109     //-----------------------------------------------------------------------
0110     void swap(deque_cnc & A) noexcept
0111     {
0112         if (this == &A) return;
0113         std::lock_guard < spinlock_t > S(spl);
0114         dq.swap(A.dq);
0115     };
0116     //
0117     //-----------------------------------------------------------------------
0118     //  S I Z E , M A X _ S I Z E , R E S I Z E
0119     //  C A P A C I T Y , E M P T Y , R E S E R V E
0120     //-----------------------------------------------------------------------
0121     //
0122     //------------------------------------------------------------------------
0123     //  function : size
0124     /// @brief return the number of elements in the deque_cnc
0125     /// @return number of elements in the deque_cnc
0126     //------------------------------------------------------------------------
0127     size_type size(void) const noexcept
0128     {
0129         std::lock_guard < spinlock_t > S(spl);
0130         return dq.size();
0131     };
0132     //
0133     //------------------------------------------------------------------------
0134     //  function :max_size
0135     /// @brief return the maximun size of the container
0136     /// @return maximun size of the container
0137     //------------------------------------------------------------------------
0138     size_type max_size(void) const noexcept
0139     {
0140         std::lock_guard < spinlock_t > S(spl);
0141         return (dq.max_size());
0142     };
0143     //
0144     //-------------------------------------------------------------------------
0145     //  function : shrink_to_fit
0146     /// @brief resize the current vector size and change to size.\n
0147     ///        If sz is smaller than the current size, delete elements to end\n
0148     ///        If sz is greater than the current size, insert elements to the
0149     ///        end with the value c
0150     /// @param [in] sz : new size of the deque_cnc after the resize
0151     /// @param [in] c : Value to insert if sz is greather than the current size
0152     /// @return none
0153     //------------------------------------------------------------------------
0154     void shrink_to_fit()
0155     {
0156         std::lock_guard < spinlock_t > S(spl);
0157         dq.shrink_to_fit();
0158     };
0159     //
0160     //------------------------------------------------------------------------
0161     //  function : empty
0162     /// @brief indicate if the map is empty
0163     /// @return true if the map is empty, false in any other case
0164     //------------------------------------------------------------------------
0165     bool empty(void) const noexcept
0166     {
0167         std::lock_guard < spinlock_t > S(spl);
0168         return (dq.empty());
0169     };
0170     //---------------------------------------------------------------------------
0171     //  function : push_back
0172     /// @brief Insert one element in the back of the container
0173     /// @param [in] D : value to insert. Can ve a value, a reference or an
0174     ///                 rvalue
0175     //---------------------------------------------------------------------------
0176     void push_back(const value_type & D)
0177     {
0178         std::lock_guard < spinlock_t > S(spl);
0179         dq.push_back(D);
0180     };
0181 
0182     //------------------------------------------------------------------------
0183     //  function : emplace_back
0184     /// @brief Insert one element in the back of the container
0185     /// @param [in] args :group of arguments for to build the object to insert
0186     //-------------------------------------------------------------------------
0187     template<class ... Args>
0188     void emplace_back(Args && ... args)
0189     {
0190         std::lock_guard < spinlock_t > S(spl);
0191         dq.emplace_back(std::forward <Args>(args) ...);
0192     };
0193     //------------------------------------------------------------------------
0194     //  function : push_back
0195     /// @brief Insert one element in the back of the container
0196     /// @param [in] D : deque to insert in the actual deque, inserting a copy
0197     ///                  of the elements
0198     /// @return reference to the deque after the insertion
0199     //------------------------------------------------------------------------
0200     template<class Allocator2>
0201     deque_cnc & push_back(const std::deque<value_type, Allocator2> & D)
0202     {
0203         std::lock_guard < spinlock_t > S(spl);
0204         for (size_type i = 0; i < D.size(); ++i)
0205             dq.push_back(D[i]);
0206         return *this;
0207     };
0208     //------------------------------------------------------------------------
0209     //  function : push_back
0210     /// @brief Insert one element in the back of the container
0211     /// @param [in] D : deque to insert in the actual deque, inserting a move
0212     ///                 of the elements
0213     /// @return reference to the deque after the insertion
0214     //------------------------------------------------------------------------
0215     deque_cnc & push_back(std::deque<value_type, Allocator> && D)
0216     {
0217         std::lock_guard < spinlock_t > S(spl);
0218         for (size_type i = 0; i < D.size(); ++i)
0219             dq.emplace_back(std::move(D[i]));
0220         return *this;
0221     };
0222     //
0223     //------------------------------------------------------------------------
0224     //  function :pop_back
0225     /// @brief erase the last element of the container
0226     //-----------------------------------------------------------------------
0227     void pop_back(void)
0228     {
0229         std::lock_guard < spinlock_t > S(spl);
0230         dq.pop_back();
0231     };
0232     //
0233     //------------------------------------------------------------------------
0234     //  function :pop_copy_back
0235     /// @brief erase the last element and return a copy over P
0236     /// @param [out] P : reference to a variable where copy the element
0237     /// @return code of the operation
0238     ///         true - Element erased
0239     ///         false - Empty tree
0240     //------------------------------------------------------------------------
0241     bool pop_copy_back(value_type & P)
0242     {   //-------------------------- begin -----------------------------
0243         std::lock_guard < spinlock_t > S(spl);
0244         if (dq.size() == 0) return false;
0245         P = dq.back();
0246         dq.pop_back();
0247         return true;
0248     };
0249     //
0250     //------------------------------------------------------------------------
0251     //  function :pop_move_back
0252     /// @brief erase the last element and move over P
0253     /// @param [out] P : reference to a variable where move the element
0254     /// @return code of the operation
0255     ///         true - Element erased
0256     ///         false - Empty tree
0257     //------------------------------------------------------------------------
0258     bool pop_move_back(value_type & P)
0259     {   //-------------------------- begin -----------------------------
0260         std::lock_guard < spinlock_t > S(spl);
0261         if (dq.size() == 0) return false;
0262         P = std::move(dq.back());
0263         dq.pop_back();
0264         return true;
0265     };
0266 
0267     //------------------------------------------------------------------------
0268     //  function : push_front
0269     /// @brief Insert one copy of the element in the front of the container
0270     /// @param [in] D : value to insert
0271     //------------------------------------------------------------------------
0272     void push_front(const value_type & D)
0273     {
0274         std::lock_guard < spinlock_t > S(spl);
0275         dq.push_front(D);
0276     };
0277 
0278     //------------------------------------------------------------------------
0279     //  function : emplace_front
0280     /// @brief Insert one element in the front of the container
0281     /// @param [in] args :group of arguments for to build the object to insert
0282     //-------------------------------------------------------------------------
0283     template<class ... Args>
0284     void emplace_front(Args && ... args)
0285     {
0286         std::lock_guard < spinlock_t > S(spl);
0287         dq.emplace_front(std::forward <Args>(args) ...);
0288     };
0289     //------------------------------------------------------------------------
0290     //  function : push_front
0291     /// @brief Insert a copy of the elements of the deque V1 in the front
0292     ///        of the container
0293     /// @param [in] V1 : deque with the elements to insert
0294     /// @return reference to the deque after the insertion
0295     //------------------------------------------------------------------------
0296     template<class Allocator2>
0297     deque_cnc & push_front(const std::deque<value_type, Allocator2> & V1)
0298     {
0299         std::lock_guard < spinlock_t > S(spl);
0300         for (size_type i = 0; i < V1.size(); ++i)
0301             dq.push_front(V1[i]);
0302         return *this;
0303     };
0304     //-----------------------------------------------------------------------
0305     //  function : push_front
0306     /// @brief Insert a move of the elements of the deque V1 in the front
0307     ///        of the container
0308     /// @param [in] V1 : deque with the elements to insert
0309     /// @return reference to the deque after the insertion
0310     //-----------------------------------------------------------------------
0311     deque_cnc & push_front(std::deque<value_type, Allocator> && V1)
0312     {
0313         std::lock_guard < spinlock_t > S(spl);
0314         for (size_type i = 0; i < V1.size(); ++i)
0315             dq.emplace_front(std::move(V1[i]));
0316         return *this;
0317     };
0318     //
0319     //-----------------------------------------------------------------------
0320     //  function :pop_front
0321     /// @brief erase the first element of the container
0322     //-----------------------------------------------------------------------
0323     void pop_front(void)
0324     {
0325         std::lock_guard < spinlock_t > S(spl);
0326         dq.pop_front();
0327     };
0328     //
0329     //-----------------------------------------------------------------------
0330     //  function :pop_copy_front
0331     /// @brief erase the first element of the tree and return a copy over P
0332     /// @param [out] P : reference to a variable where copy the element
0333     /// @return code of the operation
0334     ///         true- Element erased
0335     ///         false - Empty tree
0336     //-----------------------------------------------------------------------
0337     bool pop_copy_front(value_type & P)
0338     {   //-------------------------- begin -----------------------------
0339         std::lock_guard < spinlock_t > S(spl);
0340         if (dq.size() == 0) return false;
0341         P = dq.front();
0342         dq.pop_front();
0343         return true;
0344     };
0345     //
0346     //------------------------------------------------------------------------
0347     //  function :pop_move_front
0348     /// @brief erase the first element of the tree and return a move over P
0349     /// @param [out] P : reference to a variable where move the element
0350     /// @return code of the operation
0351     ///         true- Element erased
0352     ///         false - Empty tree
0353     //------------------------------------------------------------------------
0354     bool pop_move_front(value_type & P)
0355     {   //-------------------------- begin -----------------------------
0356         std::lock_guard < spinlock_t > S(spl);
0357         if (dq.size() == 0) return false;
0358         P = std::move(dq.front());
0359         dq.pop_front();
0360         return true;
0361     };
0362 };
0363 // end class deque_cnc
0364 
0365 //***************************************************************************
0366 };// end namespace common
0367 };// end namespace sort
0368 };// end namespace boost
0369 //***************************************************************************
0370 #endif