summaryrefslogtreecommitdiff
path: root/ACE/ace/Intrusive_List.h
blob: c5017cd730c61b54593f46ddeee8e1b087593c86 (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
/* -*- C++ -*- */

//=============================================================================
/**
 *  @file Intrusive_List.h
 *
 *  @author Carlos O'Ryan <coryan@uci.edu>
 */
//=============================================================================

#ifndef ACE_INTRUSIVE_LIST_H
#define ACE_INTRUSIVE_LIST_H
#include /**/ "ace/pre.h"

#include /**/ "ace/config-lite.h"

#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */

ACE_BEGIN_VERSIONED_NAMESPACE_DECL

/**
 * @class ACE_Intrusive_List
 *
 * @brief Implement an intrusive double linked list
 *
 * Intrusive lists assume that the elements they contain the pointers
 * required to build the list.  They are useful as light-weight
 * containers and free-lists.
 *
 * The template argument T must implement the following methods:
 *
 * - T* T::next () const;
 * - void T::next (T *);
 * - T* T::prev () const;
 * - void T::prev (T* );
 *
 * A simple way to satisfy the Intrusive_List requirements would be to
 * implement a helper class:
 *
 * class My_Object : public ACE_Intrusive_List_Node<My_Object> {<BR>
 * ....<BR>
 * };<BR>
 *
 * typedef ACE_Intrusive_List<My_Object> My_Object_List;
 *
 * However, ACE is supported on platforms that would surely get
 * confused using such templates.
 *
 * @todo The ACE_Message_Queue is an example of an intrusive list (or
 * queue) but it is not implemented in terms of this class.
 */
template <class T>
class ACE_Intrusive_List
{
public:
  /// Constructor.  Use user specified allocation strategy
  /// if specified.
  ACE_Intrusive_List () = default;

  /// Destructor.
  ~ACE_Intrusive_List () = default;

  // = Check boundary conditions.

  /// Returns true if the container is empty, otherwise returns false.
  bool is_empty () const;

  /// Insert an element at the beginning of the list
  void push_front (T *node);

  /// Insert an element at the end of the list
  void push_back (T *node);

  /// Remove the element at the beginning of the list
  T *pop_front ();

  /// Remove the element at the end of the list
  T *pop_back ();

  /// Get the element at the head of the queue
  T *head () const;

  /// Get the element at the tail of the queue
  T *tail () const;

  /// Remove a element from the list
  /**
   * Verify that the element is still in the list before removing it.
   */
  void remove (T *node);

  /// Swap two lists
  void swap(ACE_Intrusive_List<T> & rhs);

  /// Remove a element from the list without checking
  /**
   * No attempts are performed to check if T* really belongs to the
   * list.  The effects of removing an invalid element are unspecified
   */
  void unsafe_remove (T *node);

private:
  /** @name Disallow copying
   *
   */
  //@{
  ACE_Intrusive_List (const ACE_Intrusive_List<T> &);
  ACE_Intrusive_List<T>& operator= (const ACE_Intrusive_List<T> &);
  //@}

private:
  /// Head of the list
  T *head_ {};

  /// Tail of the list
  T *tail_ {};
};

ACE_END_VERSIONED_NAMESPACE_DECL

#if defined (__ACE_INLINE__)
#include "ace/Intrusive_List.inl"
#endif /* __ACE_INLINE__ */

#if defined (ACE_TEMPLATES_REQUIRE_SOURCE)
#include "ace/Intrusive_List.cpp"
#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */

#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA)
#pragma implementation ("Intrusive_List.cpp")
#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */

#include /**/ "ace/post.h"
#endif /* ACE_INTRUSIVE_LIST_H */