Bump S-nail v14.9.25 ("Lubimy Gorod"), 2024-06-27
[s-mailx.git] / include / su / view.h
blobccdf2e97ea238e27409296c91b443d1541716694
1 /*@ Generic C++ View (-of-a-collection, for iterating plus purposes) templates.
2 *@ (Merely of interest when creating a new C++ collection type.)
4 * Copyright (c) 2001 - 2020 Steffen (Daode) Nurpmeso <steffen@sdaoden.eu>.
5 * SPDX-License-Identifier: ISC
7 * Permission to use, copy, modify, and/or distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 #ifndef su_VIEW_H
20 # define su_VIEW_H
22 #ifdef CXX_DOXYGEN
23 /*!
24 * \file
25 * \ingroup VIEW
26 * \brief Generic view template(s) (super classes)
28 * Merely of interest when creating new C++ collection types.
30 #endif
32 #include <su/code.h>
33 su_USECASE_MX_DISABLED
34 #if !su_C_LANG || defined CXX_DOXYGEN
36 #define su_CXX_HEADER
37 #include <su/code-in.h>
38 NSPC_BEGIN(su)
40 template<class BASECOLLT, class KEYT, class T> class view_traits;
41 template<class VIEWTRAITS, class GBASEVIEWT> class view__base;
42 template<class VIEWTRAITS, class GBASEVIEWT> class view_unidir;
43 template<class VIEWTRAITS, class GBASEVIEWT> class view_unidir_const;
44 template<class VIEWTRAITS, class GBASEVIEWT> class view_bidir;
45 template<class VIEWTRAITS, class GBASEVIEWT> class view_bidir_const;
46 template<class VIEWTRAITS, class GBASEVIEWT> class view_random;
47 template<class VIEWTRAITS, class GBASEVIEWT> class view_random_const;
48 template<class VIEWTRAITS, class GBASEVIEWT> class view_assoc_unidir;
49 template<class VIEWTRAITS, class GBASEVIEWT> class view_assoc_unidir_const;
50 template<class VIEWTRAITS, class GBASEVIEWT> class view_assoc_bidir;
51 template<class VIEWTRAITS, class GBASEVIEWT> class view_assoc_bidir_const;
53 /*!
54 * \defgroup VIEW C++ View superclasses
55 * \ingroup COLL
56 * \brief Generic view template(s) (super classes) (\r{su/view.h})
58 * Merely of interest when creating new C++ collection types.
60 * \head1{Superclass requirements}
62 * The minimum required interface that the typesafe C++ templates require,
63 * and its expected behaviour.
64 * In general there is a basic interface and several type-specific additions
65 * which stack upon each other.
67 * \head2{Base}
69 * \list{\li{
70 * Copy constructor
71 * }\li{
72 * Assignment operator (C: \fn{_assign()})
73 * }\li{
74 * \fn{self_class &setup(super_collection &tc)}
75 * Create a tie in between this view and its parental collection instance.
76 * This is superficial: the programmer is responsible to ensure that the parent
77 * remains accessible, remains unmodified, etc.
78 * }\li{
79 * \fn{boole is_setup(void) const}
80 * }\li{
81 * \fn{boole is_same_parent(self_class const &t) const}:
82 * Whether two views are tied to the same collection object.
83 * }\li{
84 * \fn{boole is_valid(void) const}:
85 * A valid view points to an accessible slot of the collection instance.
86 * }\li{
87 * \fn{self_class &reset(void)}
88 * Invalidate the position, but keep the parent collection tied.
89 * }\li{
90 * \fn{void const *data(void) const}:
91 * \NIL is returned if \fn{is_valid()} assertion triggers.
92 * Also avaiable via \fn{operator*(void) const}
93 * and \fn{operator->(void) const}.
94 * }\li{
95 * \fn{self_class &begin(void)}:
96 * Move the \fn{is_setup()} view to the first iteratable position, if any.
97 * }\li{
98 * \fn{boole has_next(void) const}, \fn{self_class &next(void)}:
99 * Step the \c{is_valid()} view to the next position, if any.
100 * }\li{
101 * \fn{sz cmp(self_class const &t) const}:
102 * This need not compare all possible cases, only those which make sense;
103 * Equality and inequality must always be provided.
104 * Neither \fn{is_setup()} nor \fn{is_valid()} are preconditions for
105 * comparison; a non-\fn{setup()}d view shall compare less-than an
106 * \fn{is_setup()} one, ditto \fn{is_valid()}.
107 * }}
109 * \head2{Additions for views with non-constant parent}
111 * \list{\li{
112 * \fn{void *data(void)}:
113 * \NIL is returned if \fn{is_valid()} assertion triggers.
114 * Also avaiable via \fn{operator*(void)} and \fn{operator->(void)}.
115 * }\li{
116 * \fn{s32 set_data(void *dat)}:
117 * Replace the value of an \fn{is_valid()} position.
118 * Returns \err{none} upon success, and \err{einval} if the \fn{is_setup()}
119 * assertion fails.
120 * }\li{
121 * \fn{self_class &remove(void)}:
122 * Remove the current \c{is_valid()} entry, and move to the next position,
123 * if there is any.
124 * }}
126 * \head2{Additions for non-associative views, non-constant parent}
128 * \list{\li{
129 * \fn{s32 insert(void *dat)}:
130 * Insert new element after current position if that \fn{is_valid()},
131 * otherwise creates a new \fn{begin()}.
132 * Returns \err{none} and is positioned at the inserted element upon
133 * success, and \err{einval} if the \fn{is_setup()} assertion fails.
134 * }\li{
135 * \fn{s32 insert_range(self_class &startpos, self_class &endpos)}:
136 * Insert new element(s) after current position if that \fn{is_valid()},
137 * otherwise creates a new \fn{begin()} first.
138 * \a{startpos} must be \fn{is_valid()} and must not be \fn{is_same_parent()}
139 * as \THIS; if it is, it is asserted that ranges do not overlap.
141 * All positions accessible by iterating \a{startpos} will be inserted.
142 * If \a{endpos} is \fn{is_valid()} \c{startpos.is_same_parent(endpos)} must
143 * assert and the iteration does not include \a{endpos}.
144 * Returns \err{none} and is positioned at the last inserted element
145 * upon success, and \err{einval} if the \fn{is_setup()} or any of the
146 * argument assertions fail, among others.
147 * }\li{
148 * \fn{self_class &remove_range(self_class &endpos)}:
149 * Remove all elements starting at the current \fn{is_valid()} entry unless
150 * \THIS becomes invalid, or a given \fn{is_valid()} \a{endpos}ition is
151 * reached, which is not removed.
153 * If \a{endpos} \fn{is_valid()} then it must be \fn{is_same_parent()}
154 * as this view; it may also become updated in this case in order to
155 * stay at the same effective position after the operation completed:
156 * for example, removing a range from an array requires \a{endpos} to be
157 * moved further to "the front".
158 * }}
160 * \head2{Additions for associative views}
162 * \list{\li{
163 * \fn{void const *key(void) const}:
164 * \NIL is returned if the \fn{is_valid()} assertion triggers.
165 * }}
167 * \head2{Additions for associative views, non-constant parent}
169 * \list{\li{
170 * \fn{s32 reset_insert(void const *key, void *dat)}:
171 * Insert a new \a{key} / \a{value} pair in the parent.
172 * If \a{key} already exists -1 is returned, but \fn{is_valid()} is true just
173 * as for a successful insertion.
174 * }\li{
175 * \fn{s32 reset_replace(void const *key, void *dat)}:
176 * Insert a new, or update an existing \a{key} / \a{value} pair in the parent.
177 * If an existing \a{key} has been updated -1 is returned, but \fn{is_valid()}
178 * is true just as for insertion of a new \a{key}.
179 * }}
181 * \head2{Additions for non-associative unidirectional views}
183 * \list{\li{
184 * \fn{self_class &go_to(uz off)}:
185 * Move the \fn{is_setup()} view to the absolute position \a{off}.
186 * }\li{
187 * \fn{boole find(void const *dat, boole byptr)}:
188 * Search for \a{dat} in the \fn{is_setup()} view, either starting at the
189 * current position if \fn{is_valid()}, at \fn{begin()} otherwise.
190 * \a{byptr} states whether data shall be found by simple pointer comparison;
191 * if not, the \c{toolbox} of the \fn{is_setup()}d parent should be
192 * asserted (if used by the collection in question).
193 * }}
195 * \head2{Additions for associative unidirectional views}
197 * \list{\li{
198 * \fn{boole find(void const *key)}:
199 * Search for \a{key} in the \fn{is_setup()} view.
200 * }}
202 * \head2{Additions for bidirectional views}
204 * \list{\li{
205 * \fn{self_class &end(void)}:
206 * Move the \fn{is_setup()} view to the last position, if any.
207 * }\li{
208 * \fn{boole has_last(void) const}
209 * }\li{
210 * \fn{self_class &last(void)}:
211 * Move the \fn{is_valid()} view to the position before the current one,
212 * if any.
213 * }}
215 * \head2{Additions for non-associative bidirectional views}
217 * \list{\li{
218 * \fn{boole rfind(void const *dat, boole byptr)}:
219 * Search for \a{dat} in the \fn{is_setup()} view, either starting at the
220 * current position if \fn{is_valid()}, at \fn{end()} otherwise.
221 * \a{byptr} states whether data shall be found by simple pointer comparison;
222 * if not, the \c{toolbox} of the \fn{setup()}d parent should be asserted.
223 * }}
225 * \head2{Additions for non-associative random-access views}
227 * This type extends the requirement of the \fn{cmp()} function in the
228 * base set, and requires the additional results less-than,
229 * less-than-or-equal, greater-than and greater-than-or-equal.
231 * \list{\li{
232 * \fn{self_class &go_around(sz reloff)}:
233 * Move the \fn{is_valid()} view relative by \a{reloff} positions.
234 * }}
235 * @{
238 /*! \_ */
239 enum view_category{
240 view_category_non_assoc, /*!< \_ */
241 view_category_assoc /*!< \_ */
244 /*! \_ */
245 enum view_type{
246 view_type_unidir, /*!< \_ */
247 view_type_bidir, /*!< \_ */
248 view_type_random, /*!< \_ */
249 view_type_assoc_unidir, /*!< \_ */
250 view_type_assoc_bidir /*!< \_ */
253 /*! \_ */
254 template<class BASECOLLT, class KEYT, class T>
255 class view_traits{
256 public:
257 typedef BASECOLLT base_coll_type; /*!< \_ */
259 // Identical to normal traits except for view_category_assoc views
260 typedef NSPC(su)type_traits<KEYT> key_type_traits; /*!< \_ */
261 typedef NSPC(su)type_traits<T> type_traits; /*!< \_ */
264 /* @} */
266 // class view__base{{{
267 template<class VIEWTRAITS, class GBASEVIEWT>
268 class view__base{
269 protected:
270 GBASEVIEWT m_view;
272 view__base(void) : m_view() {}
273 view__base(view__base const &t) : m_view(t.m_view) {}
275 public:
276 ~view__base(void) {}
278 protected:
279 view__base &assign(view__base const &t){
280 m_view = t.m_view;
281 return *this;
283 view__base &operator=(view__base const &t) {return assign(t);}
285 public:
286 boole is_setup(void) const {return m_view.is_setup();}
288 boole is_same_parent(view__base const &t) const{
289 return m_view.is_same_parent(t.m_view);
292 boole is_valid(void) const {return m_view.is_valid();}
293 operator boole(void) const {return is_valid();}
295 protected:
296 view__base &reset(void){
297 (void)m_view.reset();
298 return *this;
301 sz cmp(view__base const &t) const {return m_view.cmp(t.m_view);}
303 public:
304 boole is_equal(view__base const &t) const {return (cmp(t) == 0);}
305 boole operator==(view__base const &t) const {return (cmp(t) == 0);}
306 boole operator!=(view__base const &t) const {return (cmp(t) != 0);}
308 // }}}
310 // Because of the various sorts of views we define helper macros.
311 // Unfortunately GCC (up to and including 3.4.2) cannot access
312 // base& _x ... _x.m_view
313 // ("is protected within this context"), but can only access
314 // base& _x ... MYSELF& y = _x ... y.m_view
315 // (and only so if we put a "using" directive, see su__VIEW_IMPL_START__BASE).
316 // To be (hopefully..) absolutely safe use a C-style cast
317 #define su__VIEW_DOWNCAST(X) ((su__VIEW_NAME&)X)
319 #define su__VIEW_IMPL_START /*{{{*/\
320 template<class VIEWTRAITS, class GBASEVIEWT>\
321 class su__VIEW_NAME : public view__base<VIEWTRAITS,GBASEVIEWT>{\
322 typedef su__VIEW_NAME<VIEWTRAITS,GBASEVIEWT> myself;\
323 typedef view__base<VIEWTRAITS,GBASEVIEWT> base;\
325 /* XXX All these typedefs could be moved to class view__base!? */\
326 typedef typename VIEWTRAITS::base_coll_type base_coll_type;\
327 typedef typename VIEWTRAITS::key_type_traits key_type_traits;\
328 typedef typename VIEWTRAITS::type_traits type_traits;\
330 /* (Simply add _key_ - for non-associative this is eq tp_const) */\
331 typedef typename key_type_traits::tp_const key_tp_const;\
332 typedef typename type_traits::type type;\
333 typedef typename type_traits::tp tp;\
334 typedef typename type_traits::tp_const tp_const;\
336 protected:\
337 /* (GCC (up to and incl. 3.4.2) does not find it otherwise) */\
338 using base::m_view;\
340 public:\
341 static NSPC(su)view_category const view_category = su__VIEW_CATEGORY;\
342 static NSPC(su)view_type const view_type = su__VIEW_TYPE;\
344 su__VIEW_NAME(void) : base() {}\
345 template<class TCOLL> explicit su__VIEW_NAME(TCOLL &tc) : base(){\
346 (void)m_view.setup(S(base_coll_type&,tc)).begin();\
348 /* (Need to offer all forms to allow additional TCOLL template(s)..) */\
349 su__VIEW_NAME(su__VIEW_NAME &t) : base(t) {}\
350 su__VIEW_NAME(su__VIEW_NAME const &t) : base(t) {}\
351 ~su__VIEW_NAME(void) {}\
353 su__VIEW_NAME &assign(su__VIEW_NAME const &t){\
354 return S(myself&,base::assign(t));\
356 su__VIEW_NAME &operator=(su__VIEW_NAME const &t) {return assign(t);}\
358 using base::is_setup;\
359 template<class TCOLL> su__VIEW_NAME &setup(TCOLL &tc){\
360 (void)m_view.setup(S(base_coll_type&,tc));\
361 return *this;\
364 using base::is_same_parent;\
366 using base::is_valid;\
367 using base::operator boole;\
369 su__VIEW_NAME &reset(void) {return S(myself&,base::reset());}\
371 tp_const data(void) const{\
372 ASSERT_RET(is_valid(), NIL);\
373 return type_traits::to_const_tp(m_view.data());\
375 tp_const operator*(void) const {return data();}\
376 tp_const operator->(void) const {return data();}\
378 su__VIEW_NAME &begin(void){\
379 ASSERT_RET(is_setup(), *this);\
380 (void)m_view.begin();\
381 return *this;\
383 template<class TCOLL> su__VIEW_NAME &begin(TCOLL &tc){\
384 (void)m_view.setup(S(base_coll_type&,tc)).begin();\
385 return *this;\
388 boole has_next(void) const{\
389 ASSERT_RET(is_valid(), FAL0);\
390 return m_view.has_next();\
392 su__VIEW_NAME &next(void){\
393 ASSERT_RET(is_valid(), *this);\
394 (void)m_view.next();\
395 return *this;\
397 su__VIEW_NAME &operator++(void) {return next();}\
399 using base::is_equal;\
400 using base::operator==;\
401 using base::operator!=;\
402 /*}}} }*/
404 #define su__VIEW_IMPL_NONCONST /*{{{*/\
405 tp data(void){\
406 ASSERT_RET(is_valid(), NIL);\
407 return type_traits::to_tp(m_view.data());\
409 s32 set_data(tp dat){\
410 ASSERT_RET(is_valid(), err::einval);\
411 return m_view.set_data(type_traits::to_vp(dat));\
413 tp operator*(void) {return data();}\
414 tp operator->(void) {return data();}\
416 su__VIEW_NAME &remove(void){\
417 ASSERT_RET(is_valid(), *this);\
418 (void)m_view.remove();\
419 return *this;\
421 /*}}}*/
423 #define su__VIEW_IMPL_CONST /*{{{*/\
424 /* (We need to cast away the 'const', but it is preserved logically..) */\
425 template<class TCOLL> explicit su__VIEW_NAME(TCOLL const &tc){\
426 (void)m_view.setup(S(base_coll_type&,C(TCOLL&,tc))).begin();\
428 /* (Need to offer all copy-forms to allow TCOLL template..) */\
429 explicit su__VIEW_NAME(su__VIEW_NAME_NONCONST<VIEWTRAITS,GBASEVIEWT> &t)\
430 : base(t){\
432 explicit su__VIEW_NAME(\
433 su__VIEW_NAME_NONCONST<VIEWTRAITS,GBASEVIEWT> const &t) : base(t) {}\
435 su__VIEW_NAME &assign(\
436 su__VIEW_NAME_NONCONST<VIEWTRAITS,GBASEVIEWT> const &t){\
437 return S(myself&,base::assign(t));\
439 su__VIEW_NAME &operator=(\
440 su__VIEW_NAME_NONCONST<VIEWTRAITS,GBASEVIEWT> const &t){\
441 return assign(t);\
444 /* (We need to cast away the 'const', but it is preserved logically..) */\
445 template<class TCOLL> su__VIEW_NAME &setup(TCOLL const &tc){\
446 (void)m_view.setup(S(base_coll_type&,C(TCOLL&,tc)));\
447 return *this;\
449 /*}}}*/
451 #define su__VIEW_IMPL_NONASSOC
453 #define su__VIEW_IMPL_NONASSOC_NONCONST /*{{{*/\
454 /* err::enone or error */\
455 s32 insert(tp dat){\
456 ASSERT_RET(is_setup(), err::einval);\
457 return m_view.insert(type_traits::to_vp(dat));\
459 s32 insert(base &startpos, base const &endpos){\
460 ASSERT_RET(is_setup(), err::einval);\
461 ASSERT_RET(startpos.is_valid(), err::einval);\
462 ASSERT_RET(!endpos.is_valid() || startpos.is_same_parent(endpos),\
463 err::einval);\
464 if(DBGOR(1, 0)){\
465 if(is_same_parent(startpos)){\
466 myself v(startpos);\
467 if(endpos.is_valid()){\
468 for(;; ++v)\
469 if(v == endpos)\
470 break;\
471 else if(!v || v == *this)\
472 return err::einval;\
473 }else{\
474 for(; v; ++v)\
475 if(v == *this)\
476 return err::einval;\
480 return m_view.insert_range(su__VIEW_DOWNCAST(startpos).m_view,\
481 su__VIEW_DOWNCAST(endpos).m_view);\
484 su__VIEW_NAME &remove(base &endpos){\
485 ASSERT_RET(is_valid(), *this);\
486 ASSERT_RET(!endpos.is_valid() || is_same_parent(endpos), *this);\
487 (void)m_view.remove_range(su__VIEW_DOWNCAST(endpos).m_view);\
488 return *this;\
490 /*}}}*/
492 #define su__VIEW_IMPL_NONASSOC_CONST
494 #define su__VIEW_IMPL_ASSOC /*{{{*/\
495 key_tp_const key(void) const{\
496 ASSERT_RET(is_valid(), NIL);\
497 return key_type_traits::to_const_tp(m_view.key());\
499 /*}}}*/
501 #define su__VIEW_IMPL_ASSOC_NONCONST /*{{{*/\
502 /* err::enone or error */\
503 s32 reset_insert(key_tp_const key, tp dat){\
504 ASSERT_RET(is_setup(), err::einval);\
505 return m_view.reset_insert(key_type_traits::to_const_vp(key),\
506 type_traits::to_vp(dat));\
508 /* err::enone or error */\
509 s32 reset_replace(key_tp_const key, tp dat){\
510 ASSERT_RET(is_setup(), err::einval);\
511 return m_view.reset_replace(key_type_traits::to_const_vp(key),\
512 type_traits::to_vp(dat));\
514 /*}}}*/
516 #define su__VIEW_IMPL_ASSOC_CONST
518 #define su__VIEW_IMPL_UNIDIR
519 #define su__VIEW_IMPL_UNIDIR_NONCONST
521 #define su__VIEW_IMPL_UNIDIR_CONST /*{{{*/\
522 /* (We need to cast away the 'const', but it is preserved logically..) */\
523 template<class TCOLL> su__VIEW_NAME &begin(TCOLL const &tc){\
524 (void)m_view.setup(S(base_coll_type&,C(TCOLL&,tc))).begin();\
525 return *this;\
527 /*}}}*/
529 #define su__VIEW_IMPL_UNIDIR_NONASSOC /*{{{*/\
530 /* is_valid() must be tested thereafter */\
531 su__VIEW_NAME &go_to(uz off){\
532 ASSERT_RET(is_setup(), *this);\
533 (void)m_view.go_to(off);\
534 return *this;\
537 boole find(tp_const dat, boole byptr=FAL0){\
538 ASSERT_RET(is_setup(), (reset(), FAL0));\
539 /* FIXME toolbox assert if !byptr */\
540 return m_view.find(type_traits::to_const_vp(dat), byptr);\
542 /*}}}*/
544 #define su__VIEW_IMPL_UNIDIR_ASSOC /*{{{*/\
545 boole find(key_tp_const key){\
546 ASSERT_RET(is_setup(), (reset(), FAL0));\
547 return m_view.find(key_type_traits::to_const_vp(key));\
549 /*}}}*/
551 #define su__VIEW_IMPL_BIDIR /*{{{*/\
552 su__VIEW_NAME &end(void){\
553 ASSERT_RET(is_setup(), *this);\
554 (void)m_view.end();\
555 return *this;\
558 boole has_last(void) const{\
559 ASSERT_RET(is_valid(), FAL0);\
560 return m_view.has_last();\
562 su__VIEW_NAME &last(void){\
563 ASSERT_RET(is_valid(), *this);\
564 (void)m_view.last();\
565 return *this;\
567 su__VIEW_NAME &operator--(void) {return last();}\
568 /*}}}*/
570 #define su__VIEW_IMPL_BIDIR_NONCONST /*{{{*/\
571 template<class TCOLL> su__VIEW_NAME &end(TCOLL &tc){\
572 (void)m_view.setup(S(base_coll_type&,tc)).end();\
573 return *this;\
575 /*}}}*/
577 #define su__VIEW_IMPL_BIDIR_CONST /*{{{*/\
578 /* (We need to cast away the 'const', but it is preserved logically..) */\
579 template<class TCOLL> su__VIEW_NAME &end(TCOLL const &tc){\
580 (void)m_view.setup(S(base_coll_type&,C(TCOLL&,tc))).end();\
581 return *this;\
583 /*}}}*/
585 #define su__VIEW_IMPL_BIDIR_NONASSOC /*{{{*/\
586 boole rfind(tp_const dat, boole byptr=FAL0){\
587 ASSERT_RET(is_setup(), (reset(), FAL0));\
588 /* FIXME toolbox assert if !byptr */\
589 return m_view.rfind(type_traits::to_const_vp(dat), byptr);\
591 /*}}}*/
593 #define su__VIEW_IMPL_BIDIR_ASSOC
595 #define su__VIEW_IMPL_RANDOM
596 #define su__VIEW_IMPL_RANDOM_NONCONST
597 #define su__VIEW_IMPL_RANDOM_CONST
599 #define su__VIEW_IMPL_RANDOM_NONASSOC /*{{{*/\
600 /* is_valid() must be tested thereafter */\
601 su__VIEW_NAME &go_around(sz reloff){\
602 ASSERT_RET(is_valid(), *this);\
603 return m_view.go_around(reloff);\
605 su__VIEW_NAME &operator+=(sz reloff) {return go_around(reloff);}\
606 su__VIEW_NAME &operator-=(sz reloff) {return go_around(-reloff);}\
607 su__VIEW_NAME operator+(sz reloff) const{\
608 su__VIEW_NAME rv(*this);\
609 ASSERT_RET(is_valid(), rv);\
610 return (rv += reloff);\
612 su__VIEW_NAME operator-(sz reloff) const{\
613 su__VIEW_NAME rv(*this);\
614 ASSERT_RET(is_valid(), rv);\
615 return (rv -= reloff);\
618 boole operator<(base const &t) const {return (base::cmp(t) < 0);}\
619 boole operator>(base const &t) const {return (base::cmp(t) > 0);}\
620 boole operator<=(base const &t) const {return (base::cmp(t) <= 0);}\
621 boole operator>=(base const &t) const {return (base::cmp(t) >= 0);}\
622 /*}}}*/
624 #define su__VIEW_IMPL_RANDOM_ASSOC
626 #define su__VIEW_IMPL_END };
628 // Puuuh. Let us go! {{{
630 #undef su__VIEW_CATEGORY
631 #define su__VIEW_CATEGORY view_category_non_assoc
633 #undef su__VIEW_TYPE
634 #define su__VIEW_TYPE view_type_unidir
636 #undef su__VIEW_NAME
637 #undef su__VIEW_NAME_NONCONST
638 #define su__VIEW_NAME view_unidir
639 #define su__VIEW_NAME_NONCONST view_unidir
640 su__VIEW_IMPL_START
641 su__VIEW_IMPL_NONCONST
642 su__VIEW_IMPL_NONASSOC
643 su__VIEW_IMPL_NONASSOC_NONCONST
644 su__VIEW_IMPL_UNIDIR
645 su__VIEW_IMPL_UNIDIR_NONCONST
646 su__VIEW_IMPL_UNIDIR_NONASSOC
647 su__VIEW_IMPL_END
649 #undef su__VIEW_NAME
650 #define su__VIEW_NAME view_unidir_const
651 su__VIEW_IMPL_START
652 su__VIEW_IMPL_CONST
653 su__VIEW_IMPL_NONASSOC
654 su__VIEW_IMPL_NONASSOC_CONST
655 su__VIEW_IMPL_UNIDIR
656 su__VIEW_IMPL_UNIDIR_CONST
657 su__VIEW_IMPL_UNIDIR_NONASSOC
658 su__VIEW_IMPL_END
660 #undef su__VIEW_TYPE
661 #define su__VIEW_TYPE view_type_bidir
663 #undef su__VIEW_NAME
664 #undef su__VIEW_NAME_NONCONST
665 #define su__VIEW_NAME view_bidir
666 #define su__VIEW_NAME_NONCONST view_bidir
667 su__VIEW_IMPL_START
668 su__VIEW_IMPL_NONCONST
669 su__VIEW_IMPL_NONASSOC
670 su__VIEW_IMPL_NONASSOC_NONCONST
671 su__VIEW_IMPL_UNIDIR
672 su__VIEW_IMPL_UNIDIR_NONCONST
673 su__VIEW_IMPL_UNIDIR_NONASSOC
674 su__VIEW_IMPL_BIDIR
675 su__VIEW_IMPL_BIDIR_NONCONST
676 su__VIEW_IMPL_BIDIR_NONASSOC
677 su__VIEW_IMPL_END
679 #undef su__VIEW_NAME
680 #define su__VIEW_NAME view_bidir_const
681 su__VIEW_IMPL_START
682 su__VIEW_IMPL_CONST
683 su__VIEW_IMPL_NONASSOC
684 su__VIEW_IMPL_NONASSOC_CONST
685 su__VIEW_IMPL_UNIDIR
686 su__VIEW_IMPL_UNIDIR_CONST
687 su__VIEW_IMPL_UNIDIR_NONASSOC
688 su__VIEW_IMPL_BIDIR
689 su__VIEW_IMPL_BIDIR_CONST
690 su__VIEW_IMPL_BIDIR_NONASSOC
691 su__VIEW_IMPL_END
693 #undef su__VIEW_TYPE
694 #define su__VIEW_TYPE view_type_random
696 #undef su__VIEW_NAME
697 #undef su__VIEW_NAME_NONCONST
698 #define su__VIEW_NAME view_random
699 #define su__VIEW_NAME_NONCONST view_random
700 su__VIEW_IMPL_START
701 su__VIEW_IMPL_NONCONST
702 su__VIEW_IMPL_NONASSOC
703 su__VIEW_IMPL_NONASSOC_NONCONST
704 su__VIEW_IMPL_UNIDIR
705 su__VIEW_IMPL_UNIDIR_NONCONST
706 su__VIEW_IMPL_UNIDIR_NONASSOC
707 su__VIEW_IMPL_BIDIR
708 su__VIEW_IMPL_BIDIR_NONCONST
709 su__VIEW_IMPL_BIDIR_NONASSOC
710 su__VIEW_IMPL_RANDOM
711 su__VIEW_IMPL_RANDOM_NONCONST
712 su__VIEW_IMPL_RANDOM_NONASSOC
713 su__VIEW_IMPL_END
715 #undef su__VIEW_NAME
716 #define su__VIEW_NAME view_random_const
717 su__VIEW_IMPL_START
718 su__VIEW_IMPL_CONST
719 su__VIEW_IMPL_NONASSOC
720 su__VIEW_IMPL_NONASSOC_CONST
721 su__VIEW_IMPL_UNIDIR
722 su__VIEW_IMPL_UNIDIR_CONST
723 su__VIEW_IMPL_UNIDIR_NONASSOC
724 su__VIEW_IMPL_BIDIR
725 su__VIEW_IMPL_BIDIR_CONST
726 su__VIEW_IMPL_BIDIR_NONASSOC
727 su__VIEW_IMPL_RANDOM
728 su__VIEW_IMPL_RANDOM_CONST
729 su__VIEW_IMPL_RANDOM_NONASSOC
730 su__VIEW_IMPL_END
732 #undef su__VIEW_CATEGORY
733 #define su__VIEW_CATEGORY view_category_assoc
735 #undef su__VIEW_TYPE
736 #define su__VIEW_TYPE view_type_assoc_unidir
738 #undef su__VIEW_NAME
739 #undef su__VIEW_NAME_NONCONST
740 #define su__VIEW_NAME view_assoc_unidir
741 #define su__VIEW_NAME_NONCONST view_assoc_unidir
742 su__VIEW_IMPL_START
743 su__VIEW_IMPL_NONCONST
744 su__VIEW_IMPL_ASSOC
745 su__VIEW_IMPL_ASSOC_NONCONST
746 su__VIEW_IMPL_UNIDIR
747 su__VIEW_IMPL_UNIDIR_NONCONST
748 su__VIEW_IMPL_UNIDIR_ASSOC
749 su__VIEW_IMPL_END
751 #undef su__VIEW_NAME
752 #define su__VIEW_NAME view_assoc_unidir_const
753 su__VIEW_IMPL_START
754 su__VIEW_IMPL_CONST
755 su__VIEW_IMPL_ASSOC
756 su__VIEW_IMPL_ASSOC_CONST
757 su__VIEW_IMPL_UNIDIR
758 su__VIEW_IMPL_UNIDIR_CONST
759 su__VIEW_IMPL_UNIDIR_ASSOC
760 su__VIEW_IMPL_END
762 #undef su__VIEW_TYPE
763 #define su__VIEW_TYPE view_type_assoc_bidir
765 #undef su__VIEW_NAME
766 #undef su__VIEW_NAME_NONCONST
767 #define su__VIEW_NAME view_assoc_bidir
768 #define su__VIEW_NAME_NONCONST view_assoc_bidir
769 su__VIEW_IMPL_START
770 su__VIEW_IMPL_NONCONST
771 su__VIEW_IMPL_ASSOC
772 su__VIEW_IMPL_ASSOC_NONCONST
773 su__VIEW_IMPL_UNIDIR
774 su__VIEW_IMPL_UNIDIR_NONCONST
775 su__VIEW_IMPL_UNIDIR_ASSOC
776 su__VIEW_IMPL_BIDIR
777 su__VIEW_IMPL_BIDIR_NONCONST
778 su__VIEW_IMPL_BIDIR_ASSOC
779 su__VIEW_IMPL_END
781 #undef su__VIEW_NAME
782 #define su__VIEW_NAME view_assoc_bidir_const
783 su__VIEW_IMPL_START
784 su__VIEW_IMPL_CONST
785 su__VIEW_IMPL_ASSOC
786 su__VIEW_IMPL_ASSOC_CONST
787 su__VIEW_IMPL_UNIDIR
788 su__VIEW_IMPL_UNIDIR_CONST
789 su__VIEW_IMPL_UNIDIR_ASSOC
790 su__VIEW_IMPL_BIDIR
791 su__VIEW_IMPL_BIDIR_CONST
792 su__VIEW_IMPL_BIDIR_ASSOC
793 su__VIEW_IMPL_RANDOM
794 su__VIEW_IMPL_RANDOM_CONST
795 su__VIEW_IMPL_RANDOM_ASSOC
796 su__VIEW_IMPL_END
798 // }}}
800 // Cleanup {{{
802 #undef su__VIEW_DOWNCAST
804 #undef su__VIEW_IMPL_START
805 #undef su__VIEW_IMPL_NONCONST
806 #undef su__VIEW_IMPL_CONST
807 #undef su__VIEW_IMPL_NONASSOC
808 #undef su__VIEW_IMPL_NONASSOC_NONCONST
809 #undef su__VIEW_IMPL_NONASSOC_CONST
810 #undef su__VIEW_IMPL_ASSOC
811 #undef su__VIEW_IMPL_ASSOC_NONCONST
812 #undef su__VIEW_IMPL_ASSOC_CONST
813 #undef su__VIEW_IMPL_UNIDIR
814 #undef su__VIEW_IMPL_UNIDIR_NONCONST
815 #undef su__VIEW_IMPL_UNIDIR_CONST
816 #undef su__VIEW_IMPL_UNIDIR_NONASSOC
817 #undef su__VIEW_IMPL_UNIDIR_ASSOC
818 #undef su__VIEW_IMPL_BIDIR
819 #undef su__VIEW_IMPL_BIDIR_NONCONST
820 #undef su__VIEW_IMPL_BIDIR_CONST
821 #undef su__VIEW_IMPL_BIDIR_NONASSOC
822 #undef su__VIEW_IMPL_BIDIR_ASSOC
823 #undef su__VIEW_IMPL_RANDOM
824 #undef su__VIEW_IMPL_RANDOM_NONCONST
825 #undef su__VIEW_IMPL_RANDOM_CONST
826 #undef su__VIEW_IMPL_RANDOM_NONASSOC
827 #undef su__VIEW_IMPL_RANDOM_ASSOC
828 #undef su__VIEW_IMPL_END
830 #undef su__VIEW_CATEGORY
831 #undef su__VIEW_TYPE
832 #undef su__VIEW_NAME
833 #undef su__VIEW_NAME_NONCONST
835 // }}}
837 NSPC_END(su)
838 #include <su/code-ou.h>
839 #endif /* !su_C_LANG || defined CXX_DOXYGEN */
840 #endif /* su_VIEW_H */
841 /* s-it-mode */