1 /*
2  *
3  *  Copyright (C) 1997-2017, OFFIS e.V.
4  *  All rights reserved.  See COPYRIGHT file for details.
5  *
6  *  This software and supporting documentation were developed by
7  *
8  *    OFFIS e.V.
9  *    R&D Division Health
10  *    Escherweg 2
11  *    D-26121 Oldenburg, Germany
12  *
13  *
14  *  Module:  ofstd
15  *
16  *  Author:  Andreas Barth
17  *
18  *  Purpose:
19  *      Defines template algorithms for contaimer classes with
20  *      interfaces similar to the C++ Standard
21  *
22  */
23 
24 #ifndef OFALGO_H
25 #define OFALGO_H
26 
27 #include "dcmtk/config/osconfig.h"    /* make sure OS specific configuration is included first */
28 #include "dcmtk/ofstd/oftypes.h"
29 
30 // Usage:
31 //  Function_type OFForEach(InputIterator_type, Function_type, first, last ,f)
32 //     Applies function f from type Function_type to the result of
33 //     derferencing every iterator in the range [first, last) starting
34 //     with first and proceeding to last -1 (first, last are of type
35 //     InputIterator_type).  Returns f.
36 //
37 //  InputIterator_type OFFind(InputIterator_type, T_type, first, last, value)
38 //     Returns the first Iterator i of type InputIterator_type in the range
39 //     [first, last) for which *i == value (of type T_type). Returns last,
40 //     if no such iterator is found
41 //
42 //  InputIterator_type OFFindIf(InputIterator_type, Predicate_type,
43 //                              first, last, pred)
44 //     Returns the first iterator i of type InputIterator_type in the range
45 //     [first, last) for which pred(*i) != false. The function pred is of
46 //     type Predicate_type. Returns last, if no such iterator is found
47 //
48 //  ForwardIterator OFAdjacentFind(ForwardIterator_type, first, last)
49 //     Returns the first iterator i of type ForwardIterator_type such
50 //     that both i and i+1 are in the range [first, last) and *i == *(i+1)
51 //     returns last, if no such iterator is found. i+1 means the successor
52 //     of i.
53 //
54 // ForwardIterator OFAdjacentFindPred(ForwardIterator_type,
55 //                                    BinaryPredicate_type,
56 //                                    first, last, pred)
57 //     Returns the first iterator i of type ForwardIterator_type such
58 //     that both i and i+1 are in the range [first, last) and
59 //     pred (*i, *(i+1)) != false.
60 //     Returns last, if no such iterator is found. i+1 means the successor
61 //     of i.
62 //
63 // Additional Remarks:
64 //   In some template functions one template parameter is another function.
65 //   Some compilers  cannot determine automatically the type of template
66 //   function parameters, so you must give  them a hint casting
67 //   the parameter function to the correct type (e.g. NeXT gcc 2.5.8)
68 
69 
70 #ifdef HAVE_STL_ALGORITHM
71 // It is possible to use the standard template library list class since the
72 // interface is nearly identical.
73 // Important: If you want to use the standard template library (STL), no
74 // variable within a namespace using a class of the STL shall have a name
75 // of one class of the STL
76 #include <algorithm>
77 #define OFForEach(InputIterator_type, Function_type, first, last, f) STD_NAMESPACE for_each((first), (last), (f))
78 #define OFFind(InputIterator_type, T_type, first, last, value) STD_NAMESPACE find((first), (last), (value))
79 #define OFFindIf(InputIterator_type, Predicate_type, first, last, pred) STD_NAMESPACE find_if((first), (last), (pred))
80 #define OFAdjacentFind(ForwardIterator_type, first, last) STD_NAMESPACE adjacent_find((first), (last))
81 #define OFAdjacentFindPred(ForwardIterator_type, BinaryPredicate_type, first, last, pred) STD_NAMESPACE adjacent_find((first), (last), (pred))
82 #else
83 
84 #ifdef HAVE_FUNCTION_TEMPLATE
85 
86 #define OFForEach(InputIterator_type, Function_type, first, last, f) OF_ForEach((first), (last), (f))
87 
88 #define OFFind(InputIterator_type, T_type, first, last, value) OF_Find((first), (last), (value))
89 
90 #define OFFindIf(InputIterator_type, Predicate_type, first, last, pred) OF_FindIf((first), (last), (pred))
91 
92 #define OFAdjacentFind(ForwardIterator_type, first, last) OF_AdjacentFind((first), (last))
93 
94 #define OFAdjacentFindPred(ForwardIterator_type, BinaryPredicate_type, first, last, pred) OF_AdjacentFind((first), (last), (pred))
95 
96 #elif defined(HAVE_STATIC_TEMPLATE_METHOD)
97 
98 #define OFForEach(InputIterator_type, Function_type, first, last, f) OF_ForEachClass<InputIterator_type, Function_type>::OF_ForEach((first), (last), (f))
99 
100 #define OFFind(InputIterator_type, T_type, first, last, value) OF_FindClass<InputIterator_type, T_type>::OF_Find((first), (last), (value))
101 
102 #define OFFindIf(InputIterator_type, Predicate_type, first, last, pred) OF_FindIfClass<InputIterator_type, Predicate_type>::OF_FindIf((first), (last), (pred))
103 
104 #define OFAdjacentFind(ForwardIterator_type, first, last) OF_AdjacentFindClass<ForwardIterator_type, int>::OF_AdjacentFind((first), (last))
105 
106 #define OFAdjacentFindPred(ForwardIterator_type, BinaryPredicate_type, first, last, pred) OF_AdjacentFindPredClass<ForwardIterator_type, BinaryPredicate_type>::OF_AdjacentFind((first), (last), (pred))
107 #else
108 #error Your C++ Compiler is not capable of compiling this code
109 #endif
110 
111 
112 template <class InputIterator, class Function>
113 #if defined(HAVE_STATIC_TEMPLATE_METHOD) && !defined(HAVE_FUNCTION_TEMPLATE)
114 class OF_ForEachClass
115 {
116 public:
117 static
118 #endif
OF_ForEach(InputIterator first,InputIterator last,Function f)119 Function OF_ForEach(InputIterator first, InputIterator last, Function f)
120 {
121     while (first != last)
122     {
123         f(*first);
124         ++first;
125     }
126     return f;
127 }
128 #if defined(HAVE_STATIC_TEMPLATE_METHOD) && !defined(HAVE_FUNCTION_TEMPLATE)
129 };
130 #endif
131 
132 template <class InputIterator, class T>
133 #if defined(HAVE_STATIC_TEMPLATE_METHOD) && !defined(HAVE_FUNCTION_TEMPLATE)
134 class OF_FindClass
135 {
136 public:
137 static
138 #endif
OF_Find(InputIterator first,InputIterator last,const T & value)139 InputIterator OF_Find(InputIterator first, InputIterator last, const T & value)
140 {
141     while (first != last && *first != value) ++ first;
142     return first;
143 }
144 #if defined(HAVE_STATIC_TEMPLATE_METHOD) && !defined(HAVE_FUNCTION_TEMPLATE)
145 };
146 #endif
147 
148 
149 template <class InputIterator, class Predicate>
150 #if defined(HAVE_STATIC_TEMPLATE_METHOD) && !defined(HAVE_FUNCTION_TEMPLATE)
151 class OF_FindIfClass
152 {
153 public:
154 static
155 #endif
OF_FindIf(InputIterator first,InputIterator last,Predicate pred)156 InputIterator OF_FindIf(InputIterator first, InputIterator last,
157                         Predicate pred)
158 {
159     while (first != last && !pred(*first)) ++first;
160     return first;
161 }
162 #if defined(HAVE_STATIC_TEMPLATE_METHOD) && !defined(HAVE_FUNCTION_TEMPLATE)
163 };
164 #endif
165 
166 template <class ForwardIterator>
167 #if defined(HAVE_STATIC_TEMPLATE_METHOD) && !defined(HAVE_FUNCTION_TEMPLATE)
168 class OF_AdjacentFindClass
169 {
170 public:
171 static
172 #endif
OF_AdjacentFind(ForwardIterator first,ForwardIterator last)173 ForwardIterator OF_AdjacentFind(ForwardIterator first, ForwardIterator last)
174 {
175     if (first == last) return last;
176     ForwardIterator next(first);
177     while (++next != last)
178     {
179         if (*first == *next) return *first;
180         ++first;
181     }
182     return last;
183 }
184 #if defined(HAVE_STATIC_TEMPLATE_METHOD) && !defined(HAVE_FUNCTION_TEMPLATE)
185 };
186 #endif
187 
188 template <class ForwardIterator, class BinaryPredicate>
189 #if defined(HAVE_STATIC_TEMPLATE_METHOD) && !defined(HAVE_FUNCTION_TEMPLATE)
190 class OF_AdjacentFindPredClass
191 {
192 public:
193 static
194 #endif
OF_AdjacentFind(ForwardIterator first,ForwardIterator last,BinaryPredicate pred)195 ForwardIterator OF_AdjacentFind(ForwardIterator first, ForwardIterator last,
196                                 BinaryPredicate pred)
197 {
198     if (first == last) return last;
199     ForwardIterator next = first;
200     while(++next != last)
201     {
202         if (pred(*first, *last)) return first;
203         ++first;
204     }
205     return last;
206 }
207 
208 #if defined(HAVE_STATIC_TEMPLATE_METHOD) && !defined(HAVE_FUNCTION_TEMPLATE)
209 };
210 #endif
211 
212 #endif
213 
214 #endif /* OFALGO_H */
215