summaryrefslogtreecommitdiff
path: root/ace/Obstack_T.h
blob: 3e24ab31925d8c8b32753445c3fcefb7741a88d6 (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
// -*- C++ -*-

//=============================================================================
/**
 *  @file    Obstack_T.h
 *
 *  $Id$
 *
 *  @author Doug Schmidt <schmidt@cs.wustl.edu>
 *  @author Nanbor Wang <nanbor@cs.wustl.edu>
 */
//=============================================================================

#ifndef ACE_OBSTACK_T_H
#define ACE_OBSTACK_T_H

#include /**/ "ace/pre.h"

#include "ace/Obchunk.h"

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

ACE_BEGIN_VERSIONED_NAMESPACE_DECL

class ACE_Allocator;

/**
 * @class ACE_Obstack_T
 *
 * @brief Define a simple "mark and release" memory allocation utility.
 *
 * The implementation is similar to the GNU obstack utility,
 * which is used extensively in the GCC compiler.
 */
template <class CHAR>
class ACE_Obstack_T
{
public:
  // = Initialization and termination methods.
  ACE_Obstack_T (size_t size = (4096 * sizeof (CHAR)) - sizeof (ACE_Obchunk),
                 ACE_Allocator *allocator_strategy = 0);
  ~ACE_Obstack_T (void);

  /// Request Obstack to prepare a block at least @a len long for building
  /// a new string.  Return -1 if fail, 0 if success.
  int request (size_t len);

  /// Inserting a new CHAR \a c into the current building
  /// block without freezing (null terminating) the block.
  /// This function will create new chunk by checking the
  /// boundary of current Obchunk.  Return
  /// the location \a c gets inserted to, or 0 if error.
  CHAR *grow (CHAR c);

  /// Inserting a new CHAR \a c into the current building
  /// block without freezing (null terminating) the block and without
  /// checking for out-of-bound error.
  void grow_fast (CHAR c);

  /// Freeze the current building block by null terminating it.
  /// Return the starting address of the current building block, 0
  /// if error occurs.
  CHAR *freeze (void);

  /// Copy the data into the current Obchunk and freeze the current
  /// block.  Return the starting address of the current building
  /// block, 0 if error occurs.  @a len specify the string length,
  /// not the actually data size.
  CHAR *copy (const CHAR *data,
              size_t len);

  /// Return the maximum @a length or @a size of a string that can be put
  /// into this Obstack. @a size = @a length * sizeof (CHAR).
  ///
  /// @deprecated No need to use this function as you can put objects of
  /// arbitrary lengths into the obstack now.
  size_t length (void) const;
  size_t size (void) const;

  /// "Unwind" the stack. If @a obj is a null pointer, everything allocated
  /// in the stack is released. Otherwise, @a obj must be an address of an
  /// object allocated in the stack. In this case, @a obj is released along
  /// with everthing allocated in the Obstack since @a obj.
  void unwind (void* obj);

  /// "Release" the entire stack of Obchunks, putting it back on the free
  /// list.
  void release (void);

  /// Dump the state of an object.
  void dump (void) const;

  /// Declare the dynamic allocation hooks.
  ACE_ALLOC_HOOK_DECLARE;

protected:
  class ACE_Obchunk *new_chunk (void);

  /// Search through the list of Obchunks and release them. Helper funtion
  /// used by unwind.
  void unwind_i (void* obj);

  /// Pointer to the allocator used by this Obstack.
  ACE_Allocator *allocator_strategy_;

  /// Current size of the Obstack;
  size_t size_;

  // Don't change the order of the following two fields.
  /// Head of the Obchunk chain.
  class ACE_Obchunk *head_;

  /// Pointer to the current Obchunk.
  class ACE_Obchunk *curr_;
};

ACE_END_VERSIONED_NAMESPACE_DECL

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

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

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

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