summaryrefslogtreecommitdiff
path: root/STL/stl.h
blob: 2d75e19ba5a6ab12af7fcfbf69f3e5a59df9a378 (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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
#ifndef __STL_H
#define __STL_H
#endif

#include <bool.h>

// Assumes MFC is included too.

//*****************************************************************************
//
// SequenceDelete
//
// DESCRIPTION:
//
//      Deletes items in an STL sequence container.  All items in the 
//      container must be pointers to objects.
//
// INPUT PARAMETERS:
//      first - An iterator.  Should point to the first item to delete.
//      last - An iterator.  Should point AFTER the last item you wish
//             to delete.
//
//*****************************************************************************

template <class ForwardIteratorClass>
void 
SequenceDelete(ForwardIteratorClass first, const ForwardIteratorClass &last)
{ 
  using namespace std;

  while ( first != last )
  {
    delete *first++;
  }
}

//*****************************************************************************
//
// MapDelete
//
// DESCRIPTION:
//
//      Deletes items in an STL map container.  All items in the container
//      must be pointers to objects.
//
// INPUT PARAMETERS:
//      first - An iterator.  Should point to the first item to delete.
//      last - An iterator.  Should point AFTER the last item you wish
//             to delete.
//
//*****************************************************************************

template <class ForwardIteratorClass>
void 
MapDelete(ForwardIteratorClass first, const ForwardIteratorClass &last)
{ 
  using namespace std;

  while ( first != last )
  {
    delete (*first++).second;
  }
}

//*****************************************************************************
//
// Comparison operators
//
// STL cannot find comparison operators at the global level.  Is this a
// compier bug??
//
// These functions cannot be templates because they will cause ambiguity 
// errors within the STL code.
//
//*****************************************************************************

//*****************************************************************************
// STL_ROUTE_ALL_GLOBALS(T1, T2) (macro)
//
// DESCRIPTION:
//
//      This macro routes all of the comparison operators for a class whose
//      operators happen to be defined at the global level.
//
// INPUT PARAMETERS:
//     T1 - The name of the left-hand-side class.
//     T2 - The name of the right-hand-side class.
// 
//*****************************************************************************

#define STL_ROUTE_ALL_GLOBALS(T1, T2) \
namespace std \
{ \
  inline bool operator == ( const T1 &s1, const T2 &s2 ) \
  { \
    return ::operator == (s1, s2); \
  } \
  inline bool operator != ( const T1 &s1, const T2 &s2 ) \
  { \
    return ::operator != (s1, s2); \
  } \
  inline bool operator > ( const T1 &s1, const T2 &s2 ) \
  { \
    return ::operator > (s1, s2); \
  } \
  inline bool operator < ( const T1 &s1, const T2 &s2 ) \
  { \
    return ::operator < (s1, s2); \
  } \
  inline bool operator >= ( const T1 &s1, const T2 &s2 ) \
  { \
    return ::operator >= (s1, s2); \
  } \
  inline bool operator <= ( const T1 &s1, const T2 &s2 ) \
  { \
    return ::operator <= (s1, s2); \
  } \
}

//*****************************************************************************
// STL_DECLARE_GLOBAL_NE(T1, T2) (macro) / Inequality
// STL_DECLARE_GLOBAL_GT(T1, T2) (macro) / Greater than
// STL_DECLARE_GLOBAL_GE(T1, T2) (macro) / Greater than or equal to
// STL_DECLARE_GLOBAL_LE(T1, T2) (macro) / Less than or equal to
//
// DESCRIPTION:
//
//      These macros duplicate the behavior in the STL's function.h file.
//      This behavior provides default implementations of certain comparison
//      operators:  !=, >, >=, and <=.
//
//      STL is designed to instantiate these operators automatically if
//      they are missing.  This convenient feature of the STL has wreaked havoc 
//      on MFC and as a result Microsoft punted and said "use the std namespace."
//      However, this introduced a new problem -- the STL can no longer
//      automatically derive !=, <, >=, and <= from the objects' existing
//      operators, because the operators are not accessible from the std
//      namespace (they are in the global namespace).  In fact, STL cannot
//      even find the default global operators (such as == between two
//      classes).  This seems like a bug in Microsoft's compiler.
//
//      If you are storing a new class of objects in an STL container and
//      want to use find() on the container, then you must declare a global
//      equality operator on the object.  Then you can either create your
//      own != operator, or derive one using STL_DECLARE_GLOBAL_NE. 
//
//      e.g., bool operator == ( const X&, const X& )
//            STL_DECLARE_GLOBAL_NE( X, X )
//
//      It's not a bad idea to declare:
//            bool operator < ( const X&, const X& ) too.
//
//      These macros should be used with classes that implement their
//      comparison operators as global functions.
//
// INPUT PARAMETERS:
//     T1 - The name of the left-hand-side class.
//     T2 - The name of the right-hand-side class.
// 
//*****************************************************************************

// Retuires == (T1, T2)
#define STL_DECLARE_GLOBAL_NE(T1, T2) \
namespace std \
{ \
  inline bool operator != ( const T1 &s1, const T2 &s2 ) \
  { \
    return !( ::operator == (s1, s2) ); \
  } \
}

// Requires < ( T2, T1 )
#define STL_DECLARE_GLOBAL_GT(T1, T2) \
namespace std \
{ \
  inline bool operator > ( const T1 &s1, const T2 &s2 ) \
  { \
    return ::operator < (s2, s1); \
  } \
}

// Requires < ( T1, T2 )
#define STL_DECLARE_GLOBAL_GE(T1, T2) \
namespace std \
{ \
  inline bool operator >= ( const T1 &s1, const T2 &s2 ) \
  { \
    return !( ::operator < (s1, s2) ); \
  } \
}

// Requires < ( T2, T1 )
#define STL_DECLARE_GLOBAL_LE(T1, T2) \
namespace std \
{ \
  inline bool operator <= ( const T1 &s1, const T2 &s2 ) \
  { \
    return !( ::operator < (s2, s1) ); \
  } \
}

//*****************************************************************************
// Route CString's comparison operators.
//*****************************************************************************

STL_ROUTE_ALL_GLOBALS(CString, CString)