Top   Types   Functions   Classes   Options   Index   Sources 

vector.hd


   1  #REM /* -*- Mode: C++ -*-
   2  #REM  *  Author: Henrik Theiling <theiling@cs.uni-sb.de>
   3  #REM  *
   4  #REM  *  @@Begin: Licencing and Copying@@
   5  #REM  *  
   6  #REM  *  Copyright (c) Henrik Theiling
   7  #REM  *  Licence Version 2, Special Version for Erwin.
   8  #REM  *  
   9  #REM  *  The term 'this software' used in the following, additional to its
  10  #REM  *  usual usage, also includes the instantiated source files generated by
  11  #REM  *  tools of this package.
  12  #REM  *  
  13  #REM  *  This software is provided 'as-is', without warranty of any kind,
  14  #REM  *  express or implied.  In no event will the authors or copyright holders
  15  #REM  *  be held liable for any damages arising from the use of this software.
  16  #REM  *  
  17  #REM  *  Permission is granted to anyone to use this software for any purpose,
  18  #REM  *  including commercial applications, and to alter it and redistribute it
  19  #REM  *  freely, subject to the following restrictions:
  20  #REM  *  
  21  #REM  *  1. The origin of this software must not be misrepresented; you must
  22  #REM  *  not claim that you wrote the original software. If you use this
  23  #REM  *  software in a product, an acknowledgment in the product documentation
  24  #REM  *  would be appreciated.
  25  #REM  *  
  26  #REM  *  2. Altered source versions must be plainly marked as such, and must
  27  #REM  *  not be misrepresented as being the original software.
  28  #REM  *  
  29  #REM  *  3. You must not use any of the names of the authors or copyright
  30  #REM  *  holders of the original software for advertising or publicity
  31  #REM  *  pertaining to distribution without specific, written prior permission.
  32  #REM  *  
  33  #REM  *  4. If you change this software and redistribute parts or all of it in
  34  #REM  *  any form, you must make the source code of the altered version of this
  35  #REM  *  software available.  As an exception, files that were generated by
  36  #REM  *  tools of this package may be used freely, including modification.
  37  #REM  *  
  38  #REM  *  5. This notice must not be removed or altered from any source
  39  #REM  *  distribution.
  40  #REM  *
  41  #REM  *  This licence is governed by the Laws of Germany.  Disputes shall be
  42  #REM  *  settled by Saarbruecken City Court.
  43  #REM  *  
  44  #REM  *  @@End: Licencing and Copying@@
  45  #REM  *
  46  #REM  *  Needs preprocessing.
  47  #REM  *    Note*: Because the replacement system is recursive and adjusts case,
  48  #REM  *    you should use template type names consisting of lower as well as
  49  #REM  *    upper case letters.
  50  #REM  *
  51  #REM  *  TODO (in no explicit order):
  52  #REM  *    - Define something like a `mostly' C++ implementation.   Then,
  53  #REM  *      many convenience C functions could be thrown away and the C++
  54  #REM  *      inline implementation would replace them completely.  (e.g.
  55  #REM  *      supply only the _raw versions.  No _string, no _vector versions
  56  #REM  *      in C).
  57  #REM  *
  58  #REM  *    - Sweep Vector_class.  Instead of having prototypes for argument
  59  #REM  *      types
  60  #REM  *           Vector_class *
  61  #REM  *           Vector_class &
  62  #REM  *      and
  63  #REM  *           Vector_t *
  64  #REM  *
  65  #REM  *      There should only be one:
  66  #REM  *           Vector_t *
  67  #REM  *
  68  #REM  *      Together with an auto-cast to this type the code should be
  69  #REM  *      clearer.  The problem is that newer versions of GCC warn about
  70  #REM  *      better conversion sequences which are very annoying.
  71  #REM  *
  72  #REM  *      Most unfortunately, Vector_class arguments become ambiguous this
  73  #REM  *      way when a cast to Vector_t * and oType * exist and both can be
  74  #REM  *      arguments to the function.
  75  #REM  *
  76  #REM  *      An alternative would be only to have
  77  #REM  *           Vector_class &
  78  #REM  *
  79  #REM  *      Then, C -> C++ interaction would work less easily.
  80  #REM  *
  81  #REM  *      Furthermore, the C++ versions of forall should use references
  82  #REM  *      instead of pointers.
  83  #REM  *
  84  #REM  *      Perhaps the easiest way is to have a thousand overloaded
  85  #REM  *      functions...  The decision is not yet done.  The problem is that
  86  #REM  *      e.g. insert oder overwrite will be fivefold overloaded then.
  87  #REM  *
  88  #REM  *    - In C++, either have the functions with suffixes _raw, _string,
  89  #REM  *      _vector, or have the overloaded ones.  Not both.  Change the
  90  #REM  *      #ifdef into a #IFEQ.
  91  #REM  *
  92  #REM  *    - shared sub-vectors should be implemented.  The data type should
  93  #REM  *      be the same, although shared sub-vectors will not support all
  94  #REM  *      functions (most notably, all modifying functions (including
  95  #REM  *      as_array()) will not be available).
  96  #REM  *
  97  #REM  *    - Make shell_quotation correct for empty string.  This should
  98  #REM  *      result in ''.
  99  #REM  *
 100  #REM  *    - Add Vector_SHRINK_EXPLICIT or the like if you do not
 101  #REM  *      want vectors to automatically shrink, but only grow.
 102  #REM  *      Add Vector_shrink() for this.
 103  #REM  *
 104  #REM  *    - For char vectors: add Vector_fgets, Vector_fgetc,
 105  #REM  *      Vector_fread, Vector_fwrite.
 106  #REM  *
 107  #REM  *    - implement Vector_ALLOW_OUTOFRANGE completely
 108  #REM  *
 109  #REM  *    - implement efficient handling of struct types (instead of
 110  #REM  *      using oType as parameter, pass (oType const &) in C++ and
 111  #REM  *      (oType const *) in C.
 112  #REM  *
 113  #REM  *    - the naming of find, rfind, is_equal is wrong compared to
 114  #REM  *      overwrite and insert.  This must be done (unfortunalely
 115  #REM  *      involving C interface incompatibilities) in version 3 of
 116  #REM  *      Erwin.
 117  #REM  *
 118  #REM  *  DONE:
 119  #REM  *    - implement detach() correctly and adjust all the nasty
 120  #REM  *      return_if_null2i (self, table) which are wrong, as table may be
 121  #REM  *      NULL if nentries==0.
 122  #REM  *      (This was actually easy, table does not need to be NULL, but point
 123  #REM  *      to a static dummy variable).
 124  #REM  *
 125  #REM  *
 126  #REM  *---------
 127  #REM  * #REPLACE_TYPE(oType_param_c,    oType,         oType const *)
 128  #REM  * #REPLACE_TYPE(oType_param_cpp,  oType,         oType const &)
 129  #REM  * #REPLACE_TYPE(oType_result_c,   oType,         oType)
 130  #REM  * #REPLACE_TYPE(oType_result_cpp, oType,         oType)
 131  #REM  * #REPLACE_TYPE(oType_ptr,        oType *,       oType *)
 132  #REM  * #REPLACE_TYPE(oType_const_ptr,  oType const *, oType const *)
 133  #REM  * #REPLACE_TYPE(oType_ref,        oType &,       oType &)
 134  #REM  * #REPLACE_TYPE(oType_const_ref,  oType const *, oType const &)
 135  #REM  *
 136  #REM  *  See the licence and copying notice below.
 137  #REM  */
 138  #PARAMETER(oType)
 139  #DESCRIPTION(Type of values stored)
 140  #CHECK
 141  #REPLACE_PERHAPS_START(oT###ypeVar,oType)
 142  #REPLACE_PERHAPS_START(oT###ypeSuffix,)
 143  #REPLACE_PERHAPS_START(oT###ypeParamSuffix,oTypeSuffix)
 144  #REPLACE_PERHAPS_START(oT###ypeParam,oType oTypeParamSuffix)
 145  #REPLACE_PERHAPS_START(oT###ypeTouched,oTypeParam)
 146  #REPLACE_PERHAPS_START(oT###ypeVarParam,oTypeVar oTypeParamSuffix)
 147  #REPLACE_PERHAPS_START(oT###ypeResultSuffix,oTypeSuffix)
 148  #REPLACE_PERHAPS_START(oT###ypeResult,oType oTypeResultSuffix)
 149  #REPLACE(Vector,Global_vector_oType)
 150  #REPLACE(NSVector,nsvector_oType)
 151  #REM isChar: up to 8 bits
 152  #REM 16 bit chars are currently not supported!  Use an explicit isChar=0, isWChar=1 for that.
 153  #REM NOTE: size of oType and char must be equal!
 154  #IFEQ(oType,char)
 155  #REPLACE_PERHAPS(isChar,1)
 156  #ENDIF
 157  #IFEQ(isChar,1)
 158  #REPLACE(Tchar,char)
 159  #ENDIF
 160  #REM isWChar: up to 32 bits (8, 16, 32 are typical).
 161  #REM NOTE: size of oType and wchar_t must be equal!
 162  #IFEQ(oType,wchar_t)
 163  #REPLACE_PERHAPS(isWChar,1)
 164  #ENDIF
 165  #IFEQ(isWChar,1)
 166  #REPLACE(Tchar,wchar_t)
 167  #ENDIF
 168  #REPLACE(TUchar,unsigned Tchar)
 169  #REPLACE(FORMAT_REPETITION, 0)
 170  #FILES(vector.cd vector_i.hd vector_u.hd)
 171  #GENERAL(Global_vector_u.ErwinHExt Vector_u.ErwinHExt)
 172  #HEADER(Vector.ErwinHExt Vector_i.ErwinHExt Vector_d.ErwinHExt Vector_f.ErwinHExt Vector_ti.ErwinHExt Vector_n.ErwinHExt)
 173  #CLASS_IDENTIFIER(Vector_class)
 174  #CLASS_IDENTIFIER(NSVector_class)
 175  #SPLIT_TARGET(Vector)
 176  #REM *****************************************************************************************
 177  #OUTPUT(Vector_f.ErwinHExt)
 178  
 179  #ifndef ERWIN_Vector_f_ErwinHExt
 180  #define ERWIN_Vector_f_ErwinHExt
 181  
 182  /* Unification of Vector_class and Vector_t: they are identical now. */
 183  struct Vector_t;
 184  #TYPEDEF_GLOBAL(aggregate Vector_t NSVector_t)
 185  
 186  #ifndef __cplusplus
 187  typedef struct Vector_t Vector_t;
 188  #endif /* not defined __cplusplus */
 189  
 190  typedef Vector_t Vector_class;
 191  #TYPEDEF_GLOBAL(aggregate Vector_class NSVector_class)
 192  
 193  typedef Vector_t *Vector_t_p;
 194  #TYPEDEF_GLOBAL(Vector_t_p NSVector_t_p)
 195  
 196  typedef Vector_t const *Vector_t_const_p;
 197  #TYPEDEF_GLOBAL(Vector_t_const_p NSVector_t_const_p)
 198  
 199  #define Vector_SIG __gen_sig__
 200  
 201  ErwinGlobalDefines
 202  
 203  #REM #DEEPDECLS(Vector,HASH_RAW,CMP/NULL,ZERO,HAS_CONSTANT_ZERO,ICOPY,OCOPY,IFREE,OFREE,CONSTRUCTOR,DESTRUCTOR)
 204  #DEEPDECLS(Vector,HASH_RAW,CMP/NULL,ZERO,ICOPY,OCOPY,IFREE,OFREE,CONSTRUCTOR,DESTRUCTOR)
 205  #REM HACK:  currently, HAS_CONSTANT_ZERO is removed.  It should be put back!
 206  #REM
 207  #REM These deep decls must be put into the _f file, otherwise the implementation might not see them.
 208  #REM Probably some programs will not require some defines to be moved from the decls.h to the
 209  #REM settings.h file because of the change, but otherwise, we might get very hard to find run-time
 210  #REM problems when the application has different sized objects than the library.
 211  #REM THIS BUG WAS VERY HARD TO FIND!
 212  
 213  #endif /* defined ERWIN_Vector_f_ErwinHExt */
 214  
 215  #REM *****************************************************************************************
 216  #OUTPUT(Vector_n.ErwinHExt)
 217  
 218  #CHECKINCLUDE(Vector)
 219  
 220  #ifdef Vector_NEED_HEADER
 221  #include "#Vector.ErwinHExt"
 222  #endif
 223  
 224  #REM *****************************************************************************************
 225  #OUTPUT(Vector_ti.ErwinHExt)
 226  
 227  #ifndef ERWIN_Vector_ti_ErwinHExt
 228  #define ERWIN_Vector_ti_ErwinHExt
 229  
 230  #define Vector_size_t_KIND UINT
 231  #define Vector_size_t_TYPE_INFO  TYPE_INFO_NAME(Vector_size_t)
 232  extern  TYPE_INFO_T(Vector_size_t);
 233  
 234  #define Vector_cnt_t_KIND SINT
 235  #define Vector_cnt_t_TYPE_INFO  TYPE_INFO_NAME(Vector_cnt_t)
 236  extern  TYPE_INFO_T(Vector_cnt_t);
 237  
 238  #define Vector_index_t_KIND SINT
 239  #define Vector_index_t_TYPE_INFO  TYPE_INFO_NAME(Vector_index_t)
 240  extern  TYPE_INFO_T(Vector_index_t);
 241  
 242  #define Vector_t_KIND STRUCT
 243  #define Vector_t_TYPE_INFO  TYPE_INFO_NAME(Vector_t)
 244  extern  TYPE_INFO_T(Vector_t);
 245  
 246  #define Vector_t_p_KIND POINTER
 247  #define Vector_t_p_TYPE_INFO  TYPE_INFO_NAME(Vector_t_p)
 248  extern  TYPE_INFO_T(Vector_t_p);
 249  
 250  #define Vector_t_const_p_KIND POINTER
 251  #define Vector_t_const_p_TYPE_INFO  TYPE_INFO_NAME(Vector_t_const_p)
 252  extern  TYPE_INFO_T(Vector_t_const_p);
 253  
 254  #define Vector_content_KIND VECTOR
 255  #define Vector_content_TYPE_INFO  TYPE_INFO_NAME(Vector_content)
 256  extern  TYPE_INFO_T(Vector_content);
 257  
 258  #define Vector_content_p_KIND POINTER
 259  #define Vector_content_p_TYPE_INFO  TYPE_INFO_NAME(Vector_content_p)
 260  extern  TYPE_INFO_T(Vector_content_p);
 261  
 262  #define Vector_class###_TYPE_INFO           Vector_t_TYPE_INFO
 263  #define Vector_class_p###_TYPE_INFO         Vector_t_p_TYPE_INFO
 264  #define Vector_class_const_p###_TYPE_INFO   Vector_t_const_p_TYPE_INFO
 265  
 266  #endif /* defined ERWIN_Vector_ti_ErwinHExt */
 267  
 268  #REM *****************************************************************************************
 269  #OUTPUT(Vector.ErwinHExt)
 270  /* -*- Mode: C -*- */
 271  #DATE
 272  /*
 273   * Author: Henrik Theiling
 274   * Description:
 275   *     Public header file for vectors with arbitrary value types.
 276   *
 277   */
 278  #LICENCE
 279  
 280  #ifdef ERWIN_DEBUG_INCLUDE
 281  #warning "Including Vector.ErwinHExt"
 282  #endif
 283  
 284  #ifndef ERWIN_Vector_ErwinHExt
 285  #define ERWIN_Vector_ErwinHExt
 286  
 287  #ifdef ERWIN_DEBUG_INCLUDE
 288  #warning "First inclusion of Vector.ErwinHExt"
 289  #endif
 290  
 291  /* Include basic configuration */
 292  #ifdef Global_ERWIN_COMPILING
 293  #  include "erwin/defs.h"
 294  #else
 295  #  include <erwin/defs.h>
 296  #endif
 297  
 298  /* Include definitions */
 299  #include "#Vector_d.ErwinHExt"
 300  
 301  /* Include basic definitions */
 302  #ifdef Global_ERWIN_COMPILING
 303  #  include "erwin/base.h"
 304  #else
 305  #  include <erwin/base.h>
 306  #endif
 307  
 308  #ifdef Global_ERWIN_COMPILING
 309  #  include "erwin/forwards.h"
 310  #else
 311  #  include <erwin/forwards.h>
 312  #endif
 313  
 314  #ifdef HAVE_STDIO_H
 315  #  include <stdio.h>
 316  #endif
 317  
 318  #IFCPPONLY
 319  #ELSE
 320  #if defined(__cplusplus)
 321  extern "C" {
 322  #endif /* __cplusplus */
 323  #ENDIF
 324  
 325  #undef Global_vector_errno
 326  #if Global_ERWIN_GLOBAL_ERRNO
 327  #  define Global_vector_errno Global_erwininternalvectorerrno
 328    /* If you compiled Erwin without the Global_ERWIN_THREAD_SAFE flag,
 329     * this variable holds global status code for vectors.
 330     */
 331  #endif
 332  
 333  #undef  Global_vector_strerror
 334  #define Global_vector_strerror(X) Global_erwininternalvectorstrerror(X)
 335    /* Returns a textual description of a given error.  This description
 336     * starts with `Error: ' or `Warning: ' or something the like
 337     * to indicate the status level.  This is then followed by a
 338     * short description phrase.
 339     */
 340  
 341  /*! enum: Global_VECTOR_OK, Global_VECTOR_ERR_*, Global_VECTOR_WARN_* */
 342  #undef  Global_VECTOR_OK
 343  #define Global_VECTOR_OK Global_ERWININTERNALVECTOROK
 344    /* No error occurred. */
 345  
 346  #undef  Global_VECTOR_IS_OK
 347  #define Global_VECTOR_IS_OK(X) Global_ERWININTERNALVECTORISOK(X)
 348    /* Find out whether the status code vector_errno indicates that everything is fine. */
 349  
 350  #undef  Global_VECTOR_IS_ERROR
 351  #define Global_VECTOR_IS_ERROR(X) Global_ERWININTERNALVECTORISERROR(X)
 352    /* Find out whether the status code vector_errno indicates that an error occured. */
 353  
 354  #undef  Global_VECTOR_IS_WARNING
 355  #define Global_VECTOR_IS_WARNING(X) Global_ERWININTERNALVECTORISWARNING(X)
 356    /* Find out whether the status code vector_errno indicates that an error occured. */
 357  
 358  #undef  Global_VECTOR_ERR_NOMEM
 359  #define Global_VECTOR_ERR_NOMEM Global_ERWININTERNALVECTORERRNOMEM
 360    /* Memory exhausted.  If you think this is a fatal error and should be
 361     * treated like a failed assertion, #define Global_ERWIN_NOMEM_IS_FATAL.
 362     */
 363  
 364  #undef  Global_VECTOR_ERR_OUTOFRANGE
 365  #define Global_VECTOR_ERR_OUTOFRANGE Global_ERWININTERNALVECTORERROUTOFRANGE
 366    /* Returned whenever an argument has a value that cannot be handled. */
 367  
 368  #undef  Global_VECTOR_ERR_TOOLARGE
 369  #define Global_VECTOR_ERR_TOOLARGE Global_ERWININTERNALVECTORERRTOOLARGE
 370    /* The vector cannot handle the new size due to the limited range of
 371     * the data type for the index. */
 372  
 373  #undef  Global_VECTOR_ERR_IO
 374  #define Global_VECTOR_ERR_IO Global_ERWININTERNALVECTORERRIO
 375    /* Operations doing I/O return this error when an I/O error occured.  Which
 376     * error it was can be determined by calling ferror(3) on the FILE * you
 377     * passed to the vector function.
 378     *
 379     * Currently, Vector_fread and Vector_fgets may return this error.
 380     */
 381  
 382  #undef  Global_VECTOR_ERR_ASSERTIONFAILED
 383  #define Global_VECTOR_ERR_ASSERTIONFAILED Global_ERWININTERNALVECTORERRASSERTIONFAILED
 384    /* Whenever an axiomatic assertion failed, this error is occured.
 385     *
 386     * Note: Something really went wrong in this case, so do not expect that
 387     *       every failed assertion allows normal control flow to continue.
 388     *       This error means the program is broken and would have crashed
 389     *       or done something bad if the assertion had not been checked.
 390     */
 391  
 392  #undef  Global_VECTOR_ERR_NOTCOMPILED
 393  #define Global_VECTOR_ERR_NOTCOMPILED Global_ERWININTERNALVECTORERRNOTCOMPILED
 394    /* If some compile time flags prevented compilation of parts a function needs
 395     * at run-time, this is returned.  Currently only the `V' argument specifier
 396     * of the format functions return this if the files where compiled with
 397     * a C compiler instead of a C++ compiler.
 398     */
 399  
 400    /*
 401     * The following are warnings only. */
 402  #undef  Global_VECTOR_WARN_OUTOFRANGE
 403  #define Global_VECTOR_WARN_OUTOFRANGE       Global_ERWININTERNALVECTORWARNOUTOFRANGE
 404    /* If a value is out of range, this warning is returned. */
 405  
 406  #undef  Global_VECTOR_WARN_EMTPY
 407  #define Global_VECTOR_WARN_EMPTY            Global_ERWININTERNALVECTORWARNEMPTY
 408    /* Vector_fgets returns this if EOF was reached and no character could be
 409     * read anymore. */
 410  
 411  #if Vector_SMALL_SIZE
 412  /* Size: 16 bit, index:32 bits.  if possible. */
 413     /* We should use 'int' in the API here, but this requires assert()s
 414      * due to different sizes, which are not yet implemented.
 415      *
 416      * Anyway, since there are not enough overflow checks for the other
 417      * settings either, we allow this to be used...
 418      */
 419  
 420     /* 16 bit sizes are large enough. */
 421     /* The index type is always 'int'. */
 422  
 423  #  ifndef Vector_PREALLOC_SIZE
 424  #    define Vector_PREALLOC_SIZE  (16*1024)
 425  #  endif
 426  #  ifndef Vector_CHUNK_SIZE
 427  #    define Vector_CHUNK_SIZE      (4*1024)
 428  #  endif
 429  #  if SIZEOF_INT == 2
 430       /* Prefer 'int' over 'short'. */
 431       typedef unsigned int Vector_size_t;
 432       typedef int          Vector_index_t;
 433  #    define Vector_MAY_BE_INVALID  (SIZEOF_VOIDP > SIZEOF_INT)
 434  #    define Vector_SIZE_INDEX_DIFF 0
 435  #  elif SIZEOF_SHORT == 2
 436       typedef unsigned short Vector_size_t;
 437       typedef int            Vector_index_t;  /* 'int' in API, not 'short' */
 438  #    define Vector_MAY_BE_INVALID  (SIZEOF_VOIDP > SIZEOF_SHORT)
 439  #    define Vector_SIZE_INDEX_DIFF 1
 440  #  else
 441       /* Hmm?  Strange.  Just use int. */
 442       typedef unsigned int Vector_size_t;
 443       typedef int          Vector_index_t;
 444  #    define Vector_MAY_BE_INVALID  (SIZEOF_VOIDP > SIZEOF_INT)
 445  #    define Vector_SIZE_INDEX_DIFF 0
 446  #  endif
 447  
 448  #elif Vector_MEDIUM_SIZE
 449  
 450     /* Try 32 bit sizes, do not use 64 bits if avoidable. */
 451     /* The index type is always 'int'. */
 452  
 453  #  ifndef Vector_PREALLOC_SIZE
 454  #    define Vector_PREALLOC_SIZE   (8*1024)
 455  #  endif
 456  #  ifndef Vector_CHUNK_SIZE
 457  #    define Vector_CHUNK_SIZE      (128*1024)
 458  #  endif
 459  
 460  #  if SIZEOF_INT == 4
 461       /* Prefer 'int' over 'short'. */
 462       typedef unsigned int Vector_size_t;
 463       typedef int          Vector_index_t;
 464  #    define Vector_MAY_BE_INVALID  (SIZEOF_VOIDP > SIZEOF_INT)
 465  #    define Vector_SIZE_INDEX_DIFF 0
 466  #  elif SIZEOF_LONG == 4 && SIZEOF_INT > SIZEOF_LONG
 467       typedef unsigned long Vector_size_t;
 468       typedef int           Vector_index_t;
 469  #    define Vector_MAY_BE_INVALID  (SIZEOF_VOIDP > SIZEOF_LONG)
 470  #    define Vector_SIZE_INDEX_DIFF 1
 471  #  elif SIZEOF_SHORT == 4
 472       typedef unsigned short Vector_size_t;
 473       typedef int            Vector_index_t;
 474  #    define Vector_MAY_BE_INVALID  (SIZEOF_VOIDP > SIZEOF_SHORT)
 475  #    define Vector_SIZE_INDEX_DIFF 0
 476  #  else
 477       /* Hmm? Just use int. */
 478       typedef unsigned int Vector_size_t;
 479       typedef int          Vector_index_t;
 480  #    define Vector_MAY_BE_INVALID  (SIZEOF_VOIDP > SIZEOF_INT)
 481  #    define Vector_SIZE_INDEX_DIFF 0
 482  #  endif
 483  
 484  #elif Vector_LARGE_INDEX
 485  
 486     /* Full size_t support (e.g. >= 2G entries on 64 bit). */
 487     /* The size and index are both '(s)size_t'.
 488      * This is a different API: we do not have an 'int' index. */
 489  #  ifndef Vector_PREALLOC_SIZE
 490  #    define Vector_PREALLOC_SIZE   (16*1024)
 491  #  endif
 492  #  ifndef Vector_CHUNK_SIZE
 493  #    define Vector_CHUNK_SIZE      (256*1024)
 494  #  endif
 495     typedef size_t  Vector_size_t;
 496     typedef ssize_t Vector_index_t;
 497  #  define Vector_MAY_BE_INVALID  (SIZEOF_VOIDP > SIZEOF_SIZE_T)
 498  #  define Vector_SIZE_INDEX_DIFF 0
 499  
 500  #else
 501  
 502     /* By default, vectors work with 'int' as index type. */
 503  #  ifndef Vector_PREALLOC_SIZE
 504  #    define Vector_PREALLOC_SIZE   (8*1024*1024)
 505  #  endif
 506  #  ifndef Vector_CHUNK_SIZE
 507  #    define Vector_CHUNK_SIZE      (128*1024)
 508  #  endif
 509     typedef unsigned int   Vector_size_t;
 510     typedef int            Vector_index_t;
 511  #  define Vector_MAY_BE_INVALID  (SIZEOF_VOIDP > SIZEOF_INT)
 512  #  define Vector_SIZE_INDEX_DIFF 0
 513  
 514  #endif
 515  
 516  
 517  typedef Vector_index_t Vector_cnt_t;
 518     /* index is always the same as cnt, it just marks a different usage */
 519  
 520  #IFEQ(isChar,1)
 521  #define Vector_Tchar_t Tchar
 522  #ENDIF
 523  
 524  typedef oType Vector_value_t;
 525  #TYPEDEF(Vector_value_t NSVector_value_t)
 526  
 527  #TYPEDEF(Vector_size_t  NSVector_size_t)
 528  #TYPEDEF(Vector_cnt_t   NSVector_cnt_t)
 529  #TYPEDEF(Vector_index_t NSVector_index_t)
 530  
 531  typedef int (*Vector_cmp_t) (oType const *, oType const *);
 532  #TYPEDEF(Vector_cmp_t NSVector_cmp_t)
 533  
 534  typedef Global_ERWIN_BOOL (*Vector_feature_t)(oTypeParam);
 535  #TYPEDEF(Vector_feature_t NSVector_feature_t)
 536  
 537  #ifndef Vector_MAP_T_DEFINED
 538  #define Vector_MAP_T_DEFINED
 539  /* In order to have oTypeResult as a result type for Vector_map_t, declare that
 540   * function yourself and define Vector_MAP_T_DEFINED.
 541   */
 542  typedef oType (*Vector_map_t)(oTypeParam);
 543  #TYPEDEF(Vector_map_t NSVector_map_t)
 544  #endif
 545  #define Vector_CMP_T_NULL ((Vector_cmp_t)NULL)
 546  
 547  #ifdef __cplusplus
 548  typedef bool (*Vector_cpp_feature_t)(oTypeParam);
 549  #TYPEDEF_CXX(Vector_cpp_feature_t NSVector_cpp_feature_t)
 550  #endif /* defined __cplusplus */
 551  
 552  #TYPEDEF(Vector_element_ptr_t NSVector_element_ptr_t)
 553  #TYPEDEF_CXX(Vector_element_ref_t NSVector_element_ref_t)
 554  #IFEQ(oType,oTypeVar)
 555  typedef oType *Vector_element_ptr_t;
 556  #ifdef __cplusplus
 557  typedef oType &Vector_element_ref_t;
 558  #endif /* defined __cplusplus */
 559  #ELSE
 560  typedef oType const *Vector_element_ptr_t;
 561  #ifdef __cplusplus
 562  typedef oType const &Vector_element_ref_t;
 563  #endif /* defined __cplusplus */
 564  #ENDIF
 565  
 566  typedef int  (*Vector_combine_t) (Vector_element_ptr_t, oType const *);
 567  #TYPEDEF(Vector_combine_t NSVector_combine_t)
 568  #define Vector_COMBINE_T_NULL ((Vector_combine_t)NULL)
 569  
 570  #IFEQ(isChar,1)
 571  #define Vector_STRING_LIT(X) X
 572  #define Vector_tchar_strlen(X) ((X) == NULL ? 0 : strlen(X))
 573       /* For wchar_t, we'll have to change this */
 574  
 575  /*
 576   * For user defined quotation methods */
 577  #TYPEDEF(aggregate Vector_quotation_method_t NSVector_quotation_method_t)
 578  typedef struct _Vector_quotation_method_t {
 579      /* This class is used for customising formatting.
 580       * The library supports several standard quotations
 581       * like C strings or Lisp, Shell, etc.  You may
 582       * want to define your own syntax by implementing
 583       * a few functions here and using
 584       * Vector_set_quotation_method() to define your style.
 585       */
 586  
 587      Tchar const *prefix;
 588      /* The prefix to print in front of a quoted string.
 589       * NULL means empty.
 590       * E.g. for C, this is |"\""|.
 591       */
 592  
 593      Tchar const *suffix;
 594      /* The suffix to print in front of a quoted string.
 595       * NULL means empty.
 596       *
 597       * E.g. for C, this is |"\""|.
 598       */
 599  
 600      Tchar const *null_name;
 601      /* The string to use for quoted output if the string to
 602       * print is NULL.  (No prefix or suffix will be used in
 603       * this case)
 604       *
 605       * E.g. for C, this is "NULL" and for Lisp, this is "nil".
 606       *
 607       * If this is NULL, an out of range error is generated when the
 608       * NULL string is encountered to be quoted.
 609       */
 610  
 611      Tchar const *empty_name;
 612      /* If this is != NULL, the empty string is exceptionally represent this way.
 613       *
 614       * Similar to null_name, but this handles the empty string.  E.g. in Unxi Shell
 615       * syntax quotation, which is currently implemented to not print string
 616       * delimiters, the empty string would in normal printing result in just that:
 617       * the empty string.  But that's wrong, so this member has the value "''" for
 618       * Shell quotation.
 619       *
 620       * If this is NULL, the string is normally printed using the other fields
 621       * and functions of this struct.
 622       */
 623  
 624      int  (*needs_quotation)(Tchar const *);
 625      /* A function that decides whether a string needs quotations.
 626       * You can either implement your own checks, or simply return
 627       * a value of 2 to let the library check each character for
 628       * quotation.
 629       *
 630       * Results:
 631       *     [0]  no, no quotation
 632       *     [1]  yes, quotation
 633       *     [2]  decide by checking results of the quoted_length function.
 634       *          If for some oType it returns != 1, it needs quotation.
 635       *     [3]  yes, quote, but leave out prefix and suffix.
 636       *     [4]  Always quote, but decide whether the prefix and suffix
 637       *          are used by checking the results of the quoted_length
 638       *          function.  If it is != 1 for some character, use them,
 639       *          otherwise leave them away.
 640       *
 641       * If the function pointer is NULL, this means to never quote.
 642       */
 643  
 644      int  (*quoted_length)(int /* previous_quotation_length */, Tchar /* tobequoted */);
 645      /* For checking individually whether to quote or not for each character:
 646       *
 647       * NULL means: literal length 1 (no quotation)
 648       *
 649       * The integer given to this function is the output of this function for the
 650       * previous characters.  The function can then decide whether and how to quote
 651       * depending on the previous value.  Initially, -1 is given.
 652       * If this function returns a negative value, its absolute value is taked as
 653       * the quoted string's length.  This is useful for indicating that a string
 654       * needs quotation even if the current character's quoted length is 1.
 655       */
 656  
 657      void (*quote)(oType * /* destination */, Tchar /* tobequoted */, int /* length */);
 658      /* The actual implementation of a quotation of one character.
 659       *
 660       * NULL means: no quotation
 661       *
 662       * This function must write exactly length non-null characters.  No null
 663       * character may follow (use memcpy instead of strcpy!)
 664       * The length argument is the output of the quoted_length function.
 665       */
 666  
 667      void (*check_quote)(oType * /* destination */, int /* length */);
 668      /* Check that the quotation has worked and eventually fix it so
 669       * that it is properly quoted.  The string passed is not
 670       * null-terminated, but instead the length is given.
 671       *
 672       * This function pointer may be NULL: in that case it is not invoked.
 673       *
 674       * NOTE: This function must not change the length of the string!
 675       *
 676       * E.g. this function is used for the Windows shell quotation method to
 677       *      swap the last two characters if they are \".  This is necessary because
 678       *      the quotation method is really weird (the backslash has two meanings):
 679       *
 680       *      +----------+-------------+---------------------+
 681       *      |! Before  |! Quoted     |                     |
 682       *      |  B\C D   | "B\C D"     |                     |
 683       *      |  B\"C D  | "B\\"C D"   |                     |
 684       *      |  B\"C D\ | "B\\"C D"\  | *not* "B\\"C D\"    |
 685       *      +----------+-------------+---------------------+
 686       *
 687       *      The last one cannot be "B\\"C D\" since a backslash before a double quote
 688       *      is interpreted as a quoted double quote.  This is prevented by the
 689       *      check_quote function.
 690       *
 691       */
 692  } Vector_quotation_method_t;
 693  
 694  #TYPEDEF(aggregate Vector_format_info_t NSVector_format_info_t)
 695  typedef struct _Vector_format_info_t {
 696      /* This class is used to store information after a
 697       * Vector_format() or the like has printed some string
 698       * into a vector.
 699       */
 700  
 701      Global_ERWIN_BOOL quoted;
 702       /* Whether the last %s in the format string was quoted. */
 703  
 704      Vector_cnt_t  pos;
 705       /* How many characters from the given string were read by the last %s in
 706        * the format string. */
 707  
 708  #ifdef __cplusplus
 709      _Vector_format_info_t ():
 710          quoted (0),
 711          pos (0)
 712      {}
 713  #endif /* defined __cplusplus */
 714  } Vector_format_info_t;
 715  
 716  #ENDIF
 717  
 718  /*
 719   * ***** handling `vector' objects: ***** */
 720  /*--BEGIN-C--*/
 721  
 722  Global_ERWIN_EXPORT
 723  Vector_t *Vector_new (void) ATTR_MALLOC;
 724     /* Create a new vector with default values.   I.e., with the
 725     * default zero element Vector_ZERO and the default initial hash table
 726     * size of Vector_INITIAL_SIZE.
 727     *
 728     */
 729  
 730  
 731  #if Vector_DYN_ZERO
 732  Global_ERWIN_EXPORT
 733  Vector_t *Vector_new_with_zero (oTypeTouched /*zero*/) ATTR_MALLOC;
 734    /* Create a vector specifying the zero element. */
 735  
 736  
 737  Global_ERWIN_EXPORT
 738  Vector_t *Vector_new_with_zero_and_initial_size (
 739      oTypeTouched /*zero*/, Vector_cnt_t /*initial_size*/) ATTR_MALLOC;
 740    /* Create a new, empty vector.  The first form uses Global_oType_zero as the zero element.
 741     *
 742     * - If \p initial_size < 0:
 743     *   the default size Vector_INITIAL_SIZE will be used.
 744     *
 745     * - If \p initial_size == 0 but Vector_MINIMAL_SIZE > 0:
 746     *    a size of 1 will be used.
 747     *
 748     * Note: The vector always has size==0 even if \p initial_size > 0.  This
 749     *       initial size is the size of the data structure used.
 750     *       The vector does not resize it until the
 751     *       vector becomes larger than that.
 752     */
 753  #endif
 754  
 755  Global_ERWIN_EXPORT
 756  Vector_t *Vector_new_with_initial_size (Vector_cnt_t /*initial_size*/) ATTR_MALLOC;
 757    /* Initialise with a given table size.  See Vector_new_with_zero_and_initial_size.
 758     */
 759  
 760  Global_ERWIN_EXPORT
 761  Vector_t *Vector_new_from_raw (
 762      oTypeVar * /*contents*/, Vector_cnt_t /*nentries*/, Vector_cnt_t /*allocsize*/) ATTR_MALLOC;
 763    /* This makes a vector from contents.   It 'steals' the pointer and makes it its
 764     * internal vector table.  It is assumed that we can (re/de)allocate the contents
 765     * using the normal Global_ERWIN_TMALLOC/REALLOC/CMALLOC/FREE mechanism.
 766     *
 767     * Initial_size is the amount of memory that is allocated.  You can safely pass less
 768     * than nentries, meaning we should assume that there are only nentries allocated
 769     * cells (this is safe behaviour).  If you know the amount that is allocated, you
 770     * should pass it to this function to improve performance by preventing unnecessary
 771     * reallocations.
 772     *
 773     * If you want to *copy* contents into a vector, use _new_with_initial_size
 774     * and _append_raw instead.
 775     *
 776     * If contents is NULL or allocsize is 0, then we invoke new_with_initial_size
 777     * instead, so whether you get a vector that has no allocated table
 778     * at all depends on the setting of Vector_ZERO_SIZE.  By default, table with
 779     * Vector_INITIAL_SIZE will be allocated.
 780     *
 781     * If allocsize is non-zero, Vector_MINIMAL_SIZE is ignored (as with the
 782     * constructors that contain _with_initial_size), so you may allocate smaller
 783     * vectors.  (A size of 0, however, is special, see previous paragraph.)
 784     */
 785  
 786  #if Vector_DYN_ZERO
 787  
 788  Global_ERWIN_EXPORT
 789  Vector_t *Vector_new_from_raw_with_zero (
 790      oTypeVar   * /*contents*/,
 791      Vector_cnt_t /*nentries*/,
 792      Vector_cnt_t /*allocsize*/,
 793      oTypeTouched /*zero*/) ATTR_MALLOC;
 794    /* Same as before but with a given zero element. */
 795  
 796  #endif
 797  
 798  Global_ERWIN_EXPORT
 799  Vector_t *Vector_new_from_vector (Vector_t * /*other*/) ATTR_MALLOC;
 800    /* This might be strange: it makes a new vector from the contents of the other
 801     * vector and then detaches the data from the other vector.  Its purpose is
 802     * mainly useful in C++ where you can clone vectors from a static vector
 803     * by this means.  E.g.:
 804     *
 805     *   :  Vector_class a;
 806     *   :  ...
 807     *   :  return Vector_new_from_vector (a);
 808     *
 809     * Or with the same effect, but without the need to use a long functions name:
 810     *     return a.copy_detach();
 811     *
 812     * A related thing is Vector_xchg(), because the above is also roughly
 813     * equivalent to:
 814     *   : Vector_t a;
 815     *   : ...
 816     *   : Vector_t *b= Vector_new();
 817     *   : Vector_xchg(&a, b);
 818     *   : return b;
 819     */
 820  
 821  Global_ERWIN_EXPORT
 822  int Vector_init (Vector_t * /*self*/) ATTR_NONNULL((1));
 823    /*
 824     * This is for initialising non-heap Vector_t objects that are allocated
 825     * manually (thus, not via Vector_new).
 826     *
 827     * Invoking this function manually is usually discouraged.  It is thought
 828     * to be for nesting data structures.  However, if you need to optimise
 829     * heap usage, it is ok to use this function.
 830     *
 831     * \errno(OK, ERR_NOMEM)
 832     */
 833  
 834  #if Vector_DYN_ZERO
 835  Global_ERWIN_EXPORT
 836  int Vector_init_with_zero_and_initial_size (
 837      Vector_t * /*self*/,
 838      oTypeTouched /*zero*/,
 839      Vector_cnt_t /*initial_size*/) ATTR_NONNULL((1));
 840    /*
 841     * This is for initialising non-heap Vector_t objects that are allocated
 842     * manually (thus, not via Vector_new).
 843     *
 844     * Invoking this function manually is usually discouraged.  It is thought
 845     * to be for nesting data structures.  However, if you need to optimise
 846     * heap usage, it is ok to use this function.
 847     *
 848     * \errno(OK, ERR_NOMEM)
 849     */
 850  #endif
 851  
 852  Global_ERWIN_EXPORT
 853  int Vector_init_with_initial_size (
 854      Vector_t * /*self*/,
 855      Vector_cnt_t /*initial_size*/) ATTR_NONNULL((1));
 856    /*
 857     * This is for initialising non-heap Vector_t objects.
 858     *
 859     * Invoking this function manually is usually discouraged.  It is thought
 860     * to be for nesting data structures.  However, if you need to optimise
 861     * heap usage, it is ok to use this function.
 862     *
 863     * \errno(OK, ERR_NOMEM)
 864     */
 865  
 866  Global_ERWIN_EXPORT
 867  void Vector_destroy (Vector_t * /*self*/);
 868    /*
 869     * This is for deleting non-heap Vector_t objects.
 870     *
 871     * Invoking this function manually is usually discouraged.  It is thought
 872     * to be for nesting data structures.  However, if you need to optimise
 873     * heap usage, it is ok to use this function.
 874     *
 875     * \errno(OK)
 876     */
 877  
 878  Global_ERWIN_EXPORT
 879  void Vector_xchg (Vector_t * /*self*/, Vector_t * /*other*/);
 880    /*
 881     * Exchanges the two vectors' contents.  No memory allocation is
 882     * performed; this is a fast O(1) operation for swapping two values.
 883     */
 884  
 885  #if !Global_ERWIN_GLOBAL_ERRNO
 886  Global_ERWIN_EXPORT
 887  int Vector_errno(Vector_t const *) ATTR_PURE ATTR_NONNULL((1));
 888    /* If you compiled Erwin with Global_ERWIN_THREAD_SAFE, this is the way
 889     * to get the status code of a given vector.
 890     *
 891     * If you do not
 892     * have a thread-safe Erwin library, there is a macro with the same name as
 893     * this function.
 894     *
 895     * \noerrno
 896     */
 897  
 898  Global_ERWIN_EXPORT
 899  void Vector_clear_errno(Vector_t const * /*self*/) ATTR_NONNULL((1));
 900    /* If you compiled Erwin with Global_ERWIN_THREAD_SAFE, this is the way
 901     * to get the status code of a given vector.
 902     *
 903     * If you do not
 904     * have a thread-safe Erwin library, there is a macro with the same name as
 905     * this function.
 906     *
 907     * \errno(OK)
 908     */
 909  
 910  #else
 911  
 912  #define Vector_errno(X) Global_vector_errno
 913    /* If you compiled Erwin without Global_ERWIN_THREAD_SAFE, Vector_errno
 914     * is just a synonym for Global_vector_errno.
 915     *
 916     * If you
 917     * have a thread-safe Erwin library, there is a function with the same name as
 918     * this macro.
 919     *
 920     * \noerrno
 921     */
 922  
 923  #define Vector_clear_errno(X)    ((void)(Global_map_errno= Global_MAP_OK))
 924    /* If the library was not compiled with Global_ERWIN_THREAD_SAFE, Vector_clear_errno(X)
 925     * is a small macro that resets the status code to Global_VECTOR_OK.
 926     *
 927     * If you
 928     * have a thread-safe Erwin library, there is a function with the same name as
 929     * this macro.
 930     *
 931     * \errno(OK)
 932     */
 933  #endif
 934  
 935  
 936  Global_ERWIN_EXPORT
 937  Vector_t *Vector_copy (Vector_t const* /*self*/);
 938    /* Copies a vector with all its elements and returns that copy.
 939     */
 940  
 941  Global_ERWIN_EXPORT
 942  Vector_t *Vector_copy_err (Vector_t const* /*self*/, int * /*err*/);
 943    /* Like Vector_copy but sets *\p err to 1 on failure.
 944     */
 945  
 946  Global_ERWIN_EXPORT
 947  int Vector_insert_subvector (
 948      Vector_t *        /*self*/,
 949      Vector_index_t    /*start_index_self*/,
 950      Vector_t const*   /*other*/,
 951      Vector_index_t    /*start_index_other*/,
 952      Vector_cnt_t      /*size*/,
 953      Global_ERWIN_BOOL /*docopy*/);
 954    /* Inserts a portion of a vector into another one. If \p size is < 0, it defines
 955     * the last element to enter. -1 therefore means: the rest of the vector starting
 956     * at \p start_index
 957     *
 958     * Returns its success.
 959     */
 960  
 961  Global_ERWIN_EXPORT
 962  Vector_t *Vector_subvector (
 963      Vector_t const* /*self*/,
 964      Vector_index_t /*start_index*/,
 965      Vector_cnt_t /*size*/,
 966      Global_ERWIN_BOOL /*docopy*/);
 967    /* Copies only a portion of the vector. The semantics of the parameters is like in
 968     * Vector_insert_subvector. */
 969  
 970  Global_ERWIN_EXPORT
 971  void Vector_delete (Vector_t* /*self*/);
 972    /* Deletes everything in the vector and the vector structure itself.
 973     * Vector_delete is NULL safe (\p self may be NULL without crash or failed
 974     * assertion).
 975     */
 976  
 977  Global_ERWIN_EXPORT
 978  void Vector_detach (Vector_t* /*self*/);
 979    /* Clears the vector by initialising a new completely empty
 980     * table not consuming any memory.  The effect is mainly that
 981     * you can use the value of Vector_as_array and Vector_as_open_array
 982     * independently from the vector.  The old function
 983     * delete_flat is now a sequence of detach() and delete().
 984     *
 985     * Note: This function should be used when the vector is not
 986     *       needed anymore after a cast to a raw array (e.g. by
 987     *       Vector_as_array).
 988     *
 989     * Compare this function with Vector_detach_as_is().  These functions
 990     * are important to distinguish if you defined Global_oType_UPDATE_POS.
 991     *
 992     * Note: use Vector_delete_array() to deallocate the memory if you retrieve
 993     *       it with, say, Vector_as_open_array().
 994     *
 995     * Note: See the documentation of Vector_delete_array and Vector INLINE_STORE!
 996     */
 997  
 998  #IFEQ(oType,oTypeVar)
 999  Global_ERWIN_EXPORT
1000  void Vector_delete_array (Vector_element_ptr_t /*array*/);
1001    /* If you extract the vector contents e.g. with Vector_as_array(), then
1002     * detach a vector to free its contents later, use this function for
1003     * freeing.  If the memory management is left with its default settings,
1004     * this is a simple free() (or delete[] if you compiled for C++ only).
1005     * But to be sure to use the right deallocator in more complex cases,
1006     * please prefer to use this function.
1007     *
1008     * Note: With Vector_INLINE_STORE, you *must only* invoke Vector_delete_array
1009     *       on arrays obtained with Vector_as_array_detach() or
1010     *       Vector_as_open_array_detach().  You *must not* invoke it
1011     *       on arrays obtained with Vector_as_array() or Vector_as_open_array()
1012     *       because these functions may return a pointer to an inlined array,
1013     *       causing a SIGSEGV in Vector_delete_array().
1014     */
1015  #ENDIF
1016  
1017  Global_ERWIN_EXPORT
1018  void Vector_detach_as_is (Vector_t* /*self*/);
1019     /* Like Vector_detach_as_is(), but does not invoke Global_oType_UPDATE_POS
1020      * for all elements to set them to -1.
1021      *
1022      * This function is only different from Vector_detach if you defined
1023      * Global_oType_UPDATE_POS.  Otherwise, it is the same.
1024      */
1025  
1026  Global_ERWIN_EXPORT
1027  int Vector_append (Vector_t* /*self*/, oTypeTouched /*value*/);
1028    /* Appends one elements, namely \p value, to the end of the vector.
1029     *
1030     * Returns its success.
1031     */
1032  
1033  Global_ERWIN_EXPORT
1034  oTypeResult Vector_zero (Vector_t const * /* self */) ATTR_PURE;
1035    /* Returns the zero element of this vector.  This need not be the same
1036     * for all vectors (you can specify it with Vector_new_with_zero) unless
1037     * you defined Vector_CONSTANT_ZERO.
1038     */
1039  
1040  /*BEGIN:IGNORE*/
1041  #if defined(Global_ERWIN_COMPILING) || Vector_ALLOW_OUTOFRANGE || Vector_RANGE_CHECK || Vector_INLINE_STORE
1042  /*END:IGNORE*/
1043  
1044  Global_ERWIN_EXPORT
1045  oTypeResult Vector_nth (Vector_t const* /*self*/, Vector_index_t /*index*/) ATTR_ERRNO_PURE;
1046    /* Returns the found element or the zero element on failure.
1047     * If \p index is out of range, a message is also output to
1048     * stderr if you defined Global_ERWIN_VERBOSE.
1049     */
1050  
1051  /*BEGIN:IGNORE*/
1052  #else
1053  #define Vector_INLINE__NTH
1054  #endif
1055  /*END:IGNORE*/
1056  
1057  Global_ERWIN_EXPORT
1058  oTypeResult Vector_nth_char (Vector_t const* /*self*/, Vector_index_t /*index*/) ATTR_ERRNO_PURE;
1059    /* Returns the found element or the zero element on failure.
1060     *
1061     * If you access the element just after the end of the vector, then
1062     * that is regarded legal in this function and the zero element is
1063     * returned.
1064     *
1065     * If \p index is out of range, a message is also output to
1066     * stderr if you defined Global_ERWIN_VERBOSE.
1067     *
1068     * Dev.Note: this is pure: cmp to Vector_nth_char_ptr and see Vector_as_array().
1069     */
1070  
1071  Global_ERWIN_EXPORT
1072  oTypeResult Vector_first (Vector_t const* /*self*/) ATTR_ERRNO_PURE;
1073    /* Returns the first element of the vector.
1074     * This is the same as
1075     *   : Vector_nth (self, 0)
1076     */
1077  
1078  Global_ERWIN_EXPORT
1079  oTypeResult Vector_last (Vector_t const* /*self*/) ATTR_ERRNO_PURE;
1080    /* Returns the last element of the vector
1081     *
1082     * This is the same as
1083     *   : Vector_nth (self, Vector_nentries (self) - 1)
1084     */
1085  
1086  
1087  Global_ERWIN_EXPORT
1088  oTypeVar Vector_modify (
1089      Vector_t* /*self*/, Vector_index_t /*index*/, oTypeTouched /*newvalue*/) ATTR_NONNULL((1));
1090    /* Returns the old value and inserts the new one at \p index.
1091     *
1092     * Nothing is freed, \p newvalue is copied if oType_OCOPY is #defined.
1093     */
1094  
1095  
1096  Global_ERWIN_EXPORT
1097  int Vector_set (
1098      Vector_t* /*self*/, Vector_index_t /*index*/, oTypeTouched /*newvalue*/) ATTR_NONNULL((1));
1099    /* Like Vector_modify, but the old value is freed using oType_OFREE instead
1100     * of being returned.
1101     *
1102     * Returns its success.
1103     */
1104  
1105  Global_ERWIN_EXPORT
1106  void Vector_swap (
1107      Vector_t * /*self*/, Vector_index_t /*index1*/, Vector_index_t /*index2*/) ATTR_NONNULL((1));
1108    /* Because using set or modify to implement swapping of two elements involves
1109     * freeing and copying elements, this functions provides a way to swap
1110     * elements without that overhead.
1111     */
1112  
1113  Global_ERWIN_EXPORT
1114  Vector_element_ptr_t Vector_nth_ptr (
1115      Vector_t * /*self*/, Vector_index_t /*index*/) ATTR_NONNULL((1));
1116    /* Returns a pointer to the element at \p index or NULL if \p index is out of
1117     * range.
1118     *
1119     * Does not output anything to stderr even if you define Global_ERWIN_VERBOSE.
1120     *
1121     * Dev.Note: not pure with ALLOW_OUTOFRANGE option.
1122     */
1123  
1124  /* Like Vector_nth_ptr, but constant in input and output type.
1125   *
1126   * Does not output anything to stderr even if you define Global_ERWIN_VERBOSE.
1127   *
1128   * Dev.Note: not pure with ALLOW_OUTOFRANGE option.
1129   */
1130  ERWIN_STATIC_INLINE
1131  oType const *Vector_nth_ptr_const (Vector_t const * self, Vector_index_t idx);
1132  
1133  ERWIN_STATIC_INLINE
1134  oType const *Vector_nth_ptr_const (Vector_t const * self, Vector_index_t idx)
1135  {
1136      return Vector_nth_ptr ((Vector_t *)self, idx);
1137  }
1138  
1139  Global_ERWIN_EXPORT
1140  Vector_element_ptr_t Vector_nth_ptr_check (Vector_t * /*self*/, Vector_index_t /*index*/);
1141    /* Returns a pointer to the element at \p index or an signals an error if
1142     * the \p index is out of range.  (This is the same behaviour towards errors
1143     * as Vector_nth has)
1144     *
1145     * Does not output anything to stderr even if you define Global_ERWIN_VERBOSE.
1146     *
1147     * Dev.Note: not pure with ALLOW_OUTOFRANGE option.
1148     */
1149  
1150  /* Like Vector_nth_ptr_check, but constant in input and output type.
1151   *
1152   * Does not output anything to stderr even if you define Global_ERWIN_VERBOSE.
1153   *
1154   * Dev.Note: not pure with ALLOW_OUTOFRANGE option.
1155   */
1156  ERWIN_STATIC_INLINE
1157  oType const *Vector_nth_ptr_check_const (Vector_t const * self, Vector_index_t idx);
1158  
1159  ERWIN_STATIC_INLINE
1160  oType const *Vector_nth_ptr_check_const (Vector_t const * self, Vector_index_t idx)
1161  {
1162      return Vector_nth_ptr_check ((Vector_t *)self, idx);
1163  }
1164  
1165  Global_ERWIN_EXPORT
1166  Vector_element_ptr_t Vector_nth_ptr_char (
1167      Vector_t * /*self*/, Vector_index_t /*index*/) ATTR_NONNULL((1));
1168    /* Returns a pointer to the element at \p index if it is in range.
1169     * If is is one too large, returns a pointer to the element after the end,
1170     * mimicking string behaviour.  That element is guaranteed to be allocated,
1171     * of couse.  If you write to that element, it only is guarateed to have
1172     * any effect up to the next change to the vector size.  Don't change that
1173     * element, though.
1174     *
1175     * Because this function is so similar to adding an integer to a 'char const *',
1176     * i.e., to get a suffix string, this function always zero-terminates the
1177     * vector like Vector_as_array() does.  So Vector_nth_ptr_char(self,0) is
1178     * equivalent to Vector_as_array().
1179     *
1180     * NOTE: This behaves a bit strange together with ALLOW_OUTOFRANGE:
1181     *    Accesses  to any element starting from a[nentries()]  make the vector
1182     *    larger for the non-const version!  This includes the nentries()th
1183     *    element, which, even if only read with this function, enlarges the
1184     *    vector due to the potential threat of the user writing to it.
1185     *
1186     * In case ALLOW_OUTOFRANGE is off, this never makes the vector larger,
1187     * but does allow access to nentries()th element.  That element is always
1188     * ensured to be ZERO, however, so you cannot write to it.
1189     *
1190     * This signals an error if the \p index is out of range.
1191     * (This is the some behaviour towards errors as Vector_nth_char has.)
1192     *
1193     * Does not output anything to stderr even if you define Global_ERWIN_VERBOSE.
1194     *
1195     * Dev.Note: not pure, see Vector_as_array().
1196     */
1197  
1198  /* Like Vector_nth_ptr_char, but constant in input and output type.
1199   *
1200   * Note that despite the 'const', this zero-terminates the vector just like
1201   * Vector_nth_ptr_char() and Vector_as_array().
1202   *
1203   * Does not output anything to stderr even if you define Global_ERWIN_VERBOSE.
1204   */
1205  ERWIN_STATIC_INLINE
1206  oType const *Vector_nth_ptr_char_const (Vector_t const * self, Vector_index_t idx);
1207  
1208  ERWIN_STATIC_INLINE
1209  oType const *Vector_nth_ptr_char_const (Vector_t const * self, Vector_index_t idx)
1210  {
1211      return Vector_nth_ptr_char ((Vector_t *)self, idx);
1212  }
1213  
1214  Global_ERWIN_EXPORT
1215  Vector_element_ptr_t Vector_first_ptr (Vector_t * /*self*/) ATTR_NONNULL((1));
1216    /* Returns a pointer to the element at index 0 or NULL if the vector is empty.
1217     *
1218     * Does not output anything to stderr even if you define Global_ERWIN_VERBOSE.
1219     *
1220     * Dev.Note: not pure with ALLOW_OUTOFRANGE option.
1221     */
1222  
1223  Global_ERWIN_EXPORT
1224  Vector_element_ptr_t Vector_last_ptr (Vector_t * /*self*/) ATTR_NONNULL((1));
1225    /* Returns a pointer to the last element or NULL if the vector is empty.
1226     *
1227     * Does not output anything to stderr even if you define Global_ERWIN_VERBOSE.
1228     *
1229     * Dev.Note: not pure with ALLOW_OUTOFRANGE option.
1230     */
1231  
1232  Global_ERWIN_EXPORT
1233  void Vector_reverse (Vector_t * /*self*/);
1234     /* Reverses the order of all elements in the vector.
1235      *
1236      * See Vector_swap, too, which is vaguely related.
1237      */
1238  
1239  Global_ERWIN_EXPORT
1240  int Vector_erase (Vector_t* /*self*/, Vector_index_t /*index*/, Vector_cnt_t /*number_of_elements*/);
1241    /* The values erased from the the vector are freed.  If \p number_of_elements
1242     * is negative, the end of the vector is cut off.  If \p index or
1243     * \p number_of_elements are out of range, they are adjusted appropriately.
1244     *
1245     * E.g.:
1246     *  - if index == -2 and count == 5:
1247     *       then elements 0,1,2 are erased,
1248     *
1249     *  - if index >= nentries:
1250     *       nothing is erased,
1251     *
1252     *  - if index + count >= nentries:
1253     *      only the tail of the vector is erased.
1254     *      However, all this is only done if Vector_ALLOW_OUTOFRANGE is true.
1255     *      Otherwise, you'll get an assertion failure in all these cases,
1256     *      because index or count are out of range.
1257     *
1258     *  - if count < 0:
1259     *     then count is adjusted to nelements - index, e.g.
1260     *     index == 2, count = -1 will cut off the last two elements of
1261     *     the vector.
1262     *     (The absolute value of count is not considered here, only the fact
1263     *     that it is < 0).  This adjustment always happens, i.e., even if
1264     *     Vector_ALLOW_OUTOFRANGE is false.
1265     *
1266     * Returns its success.
1267     *
1268     * Reference: Vector_erase_flags, Vector_swap_erase
1269     */
1270  
1271  #IFEQ(oType,oTypeVar)
1272  Global_ERWIN_EXPORT
1273  int Vector_erase_flags (
1274                  Vector_t* /* self */,
1275                  Vector_index_t       /* index */,
1276                  Vector_cnt_t       /* number_of_elements_to_delete */,
1277                  Global_ERWIN_BOOL      /* resize */,
1278                  Global_ERWIN_BOOL      /* delete_elems */);
1279    /* Like Vector_erase but you can specify whether
1280     *   - the vector should be re-allocated by \p resize
1281     *   - elements should be freed by \p delete_elems.
1282     *
1283     * Returns its success.
1284     */
1285  #ELSE
1286  Global_ERWIN_EXPORT
1287  int Vector_erase_flags (
1288                  Vector_t* /* self */,
1289                  Vector_index_t       /* index */,
1290                  Vector_cnt_t       /* number_of_elements_to_delete */,
1291                  Global_ERWIN_BOOL      /* resize */);
1292    /* Like Vector_erase but you can specify whether the vector should be
1293     * re-allocated by \p resize.
1294     *
1295     * Returns its success.
1296     */
1297  #ENDIF
1298  
1299  Global_ERWIN_EXPORT
1300  int Vector_swap_erase (
1301      Vector_t* /*self*/, Vector_index_t /*index*/, Vector_cnt_t /*number_of_elements*/);
1302    /* This is similar to Vector_erase, but instead of shifting all elements after
1303     * the ones erased, this functions copies elements from the end of the vector
1304     * into the gap.  This is faster if \p number_of_elements is small.
1305     * The order of the copied elements is reversed.
1306     *
1307     * Example:
1308     *
1309     * Vector= [0 1 2 3 4 5 6 7 8 9]
1310     *    : Vector.swap_erase(2,3)  // erases elements 2,3,4 by overwriting with 9,8,7
1311     * Vector= [0 1 9 8 7 5 6]
1312     *
1313     * There are more interesting cases, too:
1314     *
1315     * Vector= [0 1 2 3 4 5 6 7 8 9]
1316     *    : Vector.swap_erase(4,4)  // erases elements 4,5,6,7 by overwriting with 9,8
1317     * Vector= [0 1 2 3 9 8]
1318     *
1319     * Returns its success.
1320     */
1321  
1322  #IFEQ(oType,oTypeVar)
1323  Global_ERWIN_EXPORT
1324  int Vector_swap_erase_flags (
1325      Vector_t*          /* self */,
1326      Vector_index_t     /* index */,
1327      Vector_cnt_t       /* number_of_elements_to_delete */,
1328      Global_ERWIN_BOOL  /* resize */,
1329      Global_ERWIN_BOOL  /* delete_elems */);
1330    /* Like Vector_swap_erase but you can specify whether
1331     *   a) the vector should be re-allocated by \p resize
1332     *   b) elements should be freed by \p delete_elems.
1333     *
1334     * Returns its success.
1335     */
1336  #ELSE
1337  Global_ERWIN_EXPORT
1338  int Vector_swap_erase_flags (
1339      Vector_t*          /* self */,
1340      Vector_index_t     /* index */,
1341      Vector_cnt_t       /* number_of_elements_to_delete */,
1342      Global_ERWIN_BOOL  /* resize */);
1343    /* Like Vector_swap_erase but you can specify whether the vector should be
1344     * re-allocated by \p resize.
1345     *
1346     * Returns its success.
1347     */
1348  #ENDIF
1349  
1350  Global_ERWIN_EXPORT
1351  Vector_cnt_t Vector_erase_if (
1352      Vector_t* /*self*/, Vector_feature_t /* feature */, Global_ERWIN_BOOL /*value*/);
1353    /* Erases those elements that satisfy \p feature.  You can specify which
1354     * value \p feature must return for the element in order to trigger that
1355     * deletion.  So if \p value is Global_ERWIN_FALSE, the feature described
1356     * by \p feature is negated.
1357     *
1358     * The values erased from the vector are freed using oType_OFREE.
1359     *
1360     * Returns the number of elements cut out of the vector.
1361     *
1362     * Note: In CommonLisp, this is called |remove-if|.
1363     */
1364  
1365  Global_ERWIN_EXPORT
1366  Vector_cnt_t Vector_erase_equals (Vector_t* /*self*/, Vector_cmp_t /*cmp*/, Vector_combine_t /*combine*/);
1367    /* Erases the second of two adjacent elements that is equal (wrt. the
1368     * given function) to the first.  This is repeated recursively so that
1369     * groups of adjacent equal elements are reduced to one element.
1370     *
1371     * Before erasing, the function calls back combine to let the user
1372     * adjust things (e.g. copy something from the moribund entry to
1373     * the surviving one).
1374     *
1375     * The default cmp function, used if cmp is NULL, is Global_oType_CMP.
1376     *
1377     * In a sorted vector, this procedure erases all equal elements.
1378     *
1379     * The values erased from the vector are freed using oType_OFREE.
1380     *
1381     * The number of erased elements is returned.
1382     */
1383  
1384  Global_ERWIN_EXPORT
1385  Vector_cnt_t Vector_erase_zero (Vector_t* /*self*/);
1386    /* Specialised version of Vector_erase_if: deletes zero elements. */
1387  
1388  #IFEQ(oType,oTypeVar)
1389  Global_ERWIN_EXPORT
1390  Vector_cnt_t Vector_erase_if_flags (
1391          Vector_t* /*self*/,
1392          Vector_feature_t /* feature */,
1393          Global_ERWIN_BOOL /*value*/,
1394          Global_ERWIN_BOOL /*resize*/,
1395          Global_ERWIN_BOOL /*dealloc*/);
1396    /* Additional to Vector_erase_if, you can specify whether to resize the
1397     * vector or whether to deallocate the elements that are cut out.
1398     *
1399     * Returns the number of elements cut out of the vector.
1400     */
1401  
1402  #ELSE
1403  Global_ERWIN_EXPORT
1404  Vector_cnt_t Vector_erase_if_flags (
1405          Vector_t* /*self*/,
1406          Vector_feature_t /* feature */,
1407          Global_ERWIN_BOOL /*value*/,
1408          Global_ERWIN_BOOL /*resize*/);
1409    /* Additional to Vector_erase_if, you can specify whether to resize the
1410     * vector.
1411     *
1412     * Returns the number of elements cut out of the vector.
1413     */
1414  #ENDIF
1415  
1416  Global_ERWIN_EXPORT
1417  void Vector_make_heap(Vector_t * /*self*/, Vector_cmp_t /*cmp*/);
1418    /* This makes a heap.  The first element of the vector will then
1419     * be the maximum (according to the given compare function).
1420     * The others will have the Heap Property:
1421     *
1422     * : \forall i \in { 0,..,nentries-1 }:
1423     * :    nth (floor ((i-1) / 2)) >= nth(i)
1424     *
1425     * The operation takes O(n log n) time.
1426     *
1427     * This is the heap property graphically:
1428     *   :     0      n[father(i)] >= n[i], whether father(i) = floor ((i-1) / 2)
1429     *   :   1   2
1430     *   :  3 4 5 6   // Note that the indeces in our vectors are just the
1431     *   :            // other way around to
1432     *
1433     * As a special case, a vector that is sorted in reverse order is a heap.
1434     *
1435     * The default cmp function, used if cmp is NULL, is Global_oType_PRIORITY_CMP.
1436     *
1437     * NOTE:
1438     * The implementation used here has no dedicated heap_size entry.
1439     * The heap is always as large as the whole vector.
1440     *
1441     * This function checks itself when in debug mode, causing assertion failures
1442     * if the heap property is violated after operation.
1443     */
1444  
1445  Global_ERWIN_EXPORT
1446  Vector_index_t Vector_heap_left(Vector_t const * /*self*/, Vector_index_t /*i*/) ATTR_PURE;
1447     /* Returns the index of the left child of i in a heap structure.
1448      * The index i must be a valid index of the vector.
1449      * Returns something < 0 if there is no such child of i.
1450      * The left index is guaranteed to be < than the right index.
1451      *
1452      * The operation takes O(1) time.
1453      */
1454  
1455  Global_ERWIN_EXPORT
1456  Vector_index_t Vector_heap_right (Vector_t const * /*self*/, Vector_index_t /*i*/) ATTR_PURE;
1457     /* Returns the index of the left child of i in a heap structure.
1458      * The index i must be a valid index of the vector.
1459      * Returns something < 0 if there is no such child of i.
1460      * The right index is guaranteed to be > than the left index.
1461      *
1462      * The operation takes O(1) time.
1463      */
1464  
1465  Global_ERWIN_EXPORT
1466  Vector_index_t Vector_heap_father (Vector_t const * /*self*/, Vector_index_t /*i*/) ATTR_PURE;
1467     /* Returns the index of the left child of i in a heap structure.
1468      * The index i must be a valid index of the vector.
1469      * Returns something < 0 if i does not have a father, i.e., if i == 0.
1470      *
1471      * The operation takes O(1) time.
1472      */
1473  
1474  Global_ERWIN_EXPORT
1475  oTypeVar Vector_heap_extract (Vector_t * /*self*/, Vector_cmp_t /*cmp*/) ATTR_NONNULL((1));
1476    /* This extracts the maximum from the heap, returns it, shrinks the
1477     * vector, and re-heapifies it.  See Vector_make_heap()
1478     * and Vector_heap_sink().  You may only invoke this for vectors that
1479     * have the heap property and have at least one element.
1480     *
1481     * The operation takes O(log n) time, since it reinvokes Vector_heap_sink.
1482     *
1483     * The default cmp function, used if cmp is NULL, is Global_oType_PRIORITY_CMP.
1484     *
1485     * This function checks the input and itself when in debug mode, causing
1486     * assertion failures if the heap property is violated.
1487     * Note that this check takes O(n) time, so the function is significantly
1488     * slower during debugging.  If you don't want this, you may
1489     *
1490     *   : #define Vector_DEBUG_EXPENSIVE_CHECKS        0
1491     * or (for all vectors)
1492     *   : #define Global_VECTOR_DEBUG_EXPENSIVE_CHECKS 0
1493     *
1494     * Note: this returns oTypeVar instead of oTypeResult (if these are different),
1495     * because the element is removed, so no reference can be returned.
1496     */
1497  
1498  Global_ERWIN_EXPORT
1499  void Vector_heap_raise (
1500      Vector_t * /*self*/, Vector_index_t /*i*/, Vector_cmp_t /*cmp*/) ATTR_NONNULL((1));
1501    /* The operation checks for element i whether its priority has increased.
1502     * it so, the heap property is re-established.
1503     *
1504     * The operation takes O(log n) time.
1505     *
1506     * The default cmp function, used if cmp is NULL, is Global_oType_PRIORITY_CMP.
1507     *
1508     * This function checks itself when in debug mode, causing
1509     * assertion failures if the heap property is violated after operation.
1510     * Such an assertion failure may also mean that the vector was no
1511     * heap (apart from the element i) before this operation.
1512     * Note that this check takes O(n) time, so the function is significantly
1513     * slower during debugging.  If you don't want this, you may
1514     *
1515     *   : #define Vector_DEBUG_EXPENSIVE_CHECKS        0
1516     * or (for all vectors)
1517     *   : #define Global_VECTOR_DEBUG_EXPENSIVE_CHECKS 0
1518     */
1519  
1520  Global_ERWIN_EXPORT
1521  void Vector_heap_sink (
1522      Vector_t * /*self*/, Vector_index_t /*i*/, Vector_cmp_t /*cmp*/) ATTR_NONNULL((1));
1523    /* The opposite of Vector_heap_raise: it checks whether the value of i
1524     * has decresed and if so, re-establishes the heap property.
1525     *
1526     * This operation is often called 'heapify'.  Because it is related to
1527     * heap_raise by being its opposite, we'll call it heap_sink here.
1528     *
1529     * The operation takes O(log n) time.
1530     *
1531     * The default cmp function, used if cmp is NULL, is Global_oType_PRIORITY_CMP.
1532     *
1533     * See Vector_heap_raise() for more info.
1534     *
1535     * Note that this function does not do debug checks of the heap property,
1536     * because it may be used to construct a heap, so one of its purposes is to
1537     * be invoked on heaps.  We might add a check for a partial heap property
1538     * later, though.
1539     */
1540  
1541  Global_ERWIN_EXPORT
1542  void Vector_heap_fix (
1543      Vector_t * /*self*/, Vector_index_t /*i*/, Vector_cmp_t /*cmp*/) ATTR_NONNULL((1));
1544    /* Fix the position of element at index i according to its new priority.
1545     *
1546     * The operation takes O(log n) time.
1547     *
1548     * The default cmp function, used if cmp is NULL, is Global_oType_PRIORITY_CMP.
1549     *
1550     * This is an abbreviation for:
1551     *    : Vector_heap_raise (self, i, cmp);
1552     *    : Vector_heap_sink  (self, i, cmp);
1553     */
1554  
1555  Global_ERWIN_EXPORT
1556  int Vector_heap_insert (
1557      Vector_t * /*self*/, oTypeParam /*elem*/, Vector_cmp_t /*cmp*/) ATTR_NONNULL((1));
1558    /* This function inserts an element into a heap and re-establishes the
1559     * heap property.
1560     *
1561     * This operation is an abbreviation for:
1562     *    : Vector_append (self, elem);
1563     *    : Vector_heap_increase (self, Vector_nentries(s) - 1, cmp);
1564     *
1565     * Thus the operation takes O(log n) time.
1566     *
1567     * The default cmp function, used if cmp is NULL, is Global_oType_PRIORITY_CMP.
1568     *
1569     * The success is returned.
1570     *
1571     * This function checks the input (and itself indirectly via Vector_heap_raise) when
1572     * in debug mode, causing assertion failures if the heap property is violated.
1573     * Note that this check takes O(n) time, so the function is significantly
1574     * slower during debugging.  If you don't want this, you may
1575     *
1576     *    : #define Vector_DEBUG_EXPENSIVE_CHECKS        0
1577     * or (for all vectors):
1578     *    : #define Global_VECTOR_DEBUG_EXPENSIVE_CHECKS 0
1579     */
1580  
1581  Global_ERWIN_EXPORT
1582  void Vector_heap_erase (
1583      Vector_t * /*self*/, Vector_index_t /*i*/, Vector_cmp_t /*cmp*/) ATTR_NONNULL((1));
1584    /* This function deletes an element from the heap and re-establishes the
1585     * heap property.
1586     *
1587     * This operation is an abbreviation for:
1588     *    : Vector_swap (self, i, Vector_nentries(s) - 1);
1589     *    : Vector_chop (self, 1);
1590     *    : Vector_heap_sink (self, i, cmp);
1591     *
1592     * Thus the operation takes O(log n) time.
1593     *
1594     * The default cmp function, used if cmp is NULL, is Global_oType_PRIORITY_CMP.
1595     *
1596     * The success is returned.
1597     *
1598     * This function checks the input (and itself indirectly via Vector_heap_raise) when
1599     * in debug mode, causing assertion failures if the heap property is violated.
1600     * Note that this check takes O(n) time, so the function is significantly
1601     * slower during debugging.  If you don't want this, you may
1602     *
1603     *   : #define Vector_DEBUG_EXPENSIVE_CHECKS        0
1604     * or (for all vectors)
1605     *   : #define Global_VECTOR_DEBUG_EXPENSIVE_CHECKS 0
1606     */
1607  
1608  Global_ERWIN_EXPORT
1609  void Vector_heap_sort (Vector_t * /*self*/, Vector_cmp_t /*cmp*/);
1610     /* Re-builds the heap structure for the given element.
1611      * This is one of three sort functions available for vectors:
1612      *
1613      *   +------------------+------------+------------+------------+---------+-------------+
1614      *   |! Function        |! Algorithm |! Typical   |! Worst     |! Space  |!  Stability |
1615      *   | Vector_qsort     | Quicksort  | O(n log n) | O(n)       | O(1)    | not stable  |
1616      *   | Vector_heap_sort | Heapsort   | O(n log n) | O(n log n) | O(1)    | not stable  |
1617      *   | Vector_sort      | Mergesort  | O(n log n) | O(n log n) | O(n)    | stable      |
1618      *   +------------------+------------+------------+------------+---------+-------------+
1619      *
1620      * The default cmp function, used if cmp is NULL, is Global_oType_PRIORITY_CMP.
1621      *
1622      * NOTE: This uses a different comparison function by default.  Just in case
1623      *       you defined it (or differently)...
1624      *
1625      * FIXME: We should implement bubblesort as well, since it is very fast if
1626      *        only few elements have changed.
1627      *
1628      * The operation takes O(n log n) time.
1629      */
1630  
1631  Global_ERWIN_EXPORT
1632  int Vector_priority_cmp (Vector_t const *, Vector_t const *, Vector_cmp_t /*cmp*/);
1633      /* Similar to Vector_cmp, with two differences:
1634       *    - it uses Global_oType_PRIORITY_CMP as its default comparison
1635       *      function
1636       *    - it uses lexical ordering as its default, unless you define
1637       *      Vector_PRIORITY_COMPARE_LEXICOGRAPHICALLY to 0.
1638       *
1639       * This function is NULL safe.  NULL is smaller than any
1640       * other vector.
1641       *
1642       * If cmp is NULL, Global_oType_PRIORITY_CMP will be used.  If that is not
1643       * defined, an error will occur.
1644       */
1645  
1646  Global_ERWIN_EXPORT
1647  int Vector_chop (Vector_t * /*self*/, Vector_cnt_t /*count*/);
1648    /* Cuts off the last \p count elements of a vector.
1649     *
1650     * This is actually nothing more than an abbreviation for:
1651     *   : (Assert that count is >= 0)
1652     *   : Vector_erase(self, Vector_nentries(self)-count, count);
1653     *
1654     * This functions generates an assertion failure if the number of
1655     * elements to chop is greater than the number of elements in the
1656     * vector.  However, if Vector_ALLOW_OUTOFRANGE is true, then
1657     * this operation simply clears the vector without assertion failure
1658     * in this case.
1659     *
1660     * Due to the fact that the equivalent using Vector_swap_erase is
1661     * very trivial: Vector_swap_erase (self, 0, 1), there is no
1662     * Vector_swap_chop() in C (but in C++, we still have it).
1663     *
1664     * Returns its success.
1665     */
1666  
1667  #IFEQ(oType,oTypeVar)
1668  Global_ERWIN_EXPORT
1669  int Vector_chop_flags (
1670          Vector_t * /* self */,
1671          Vector_cnt_t        /* count */,
1672          Global_ERWIN_BOOL       /* resize */,
1673          Global_ERWIN_BOOL       /* delete_elems */);
1674    /* Like Vector_chop you can specify the deallocation behaviour.
1675     *
1676     * Returns its success.
1677     */
1678  #ELSE
1679  Global_ERWIN_EXPORT
1680  int Vector_chop_flags (
1681          Vector_t * /* self */,
1682          Vector_cnt_t        /* number_of_elements_to_erase_off */,
1683          Global_ERWIN_BOOL       /* resize */);
1684    /* Like Vector_chop you can specify the deallocation behaviour.
1685     *
1686     * Returns its success.
1687     */
1688  #ENDIF
1689  
1690  Global_ERWIN_EXPORT
1691  oTypeVar Vector_last_chop1 (Vector_t * /*self*/) ATTR_NONNULL((1));
1692    /* Cuts off the last element of the vector and returns it.
1693     * Like a pop on a stack.
1694     */
1695  
1696  Global_ERWIN_EXPORT
1697  oTypeVar Vector_first_swap_chop1 (Vector_t * /*self*/) ATTR_NONNULL((1));
1698    /* Cuts off the first element of the vector like Vector_swap_erase()
1699     * and returns it.  This is like Vector_heap_extract() without
1700     * heap_sink().
1701     */
1702  
1703  Global_ERWIN_EXPORT
1704  int Vector_append_raw (
1705          Vector_t *    /*self*/,
1706          oType const * /*elements*/,
1707          Vector_cnt_t  /*count*/) ATTR_NONNULL((1));
1708    /* Append \p count elements to the end of the vector.
1709     *
1710     * This is a frontend to Vector_insert_raw which lets you specify an insertion
1711     * position.
1712     *
1713     * Returns its success.
1714     */
1715  
1716  Global_ERWIN_EXPORT
1717  int Vector_append_no_copy (
1718          Vector_t *       /* self */,
1719          oTypeVar const * /* theelements */,
1720          Vector_cnt_t              /* number_of_elements_to_insert*/) ATTR_NONNULL((1));
1721    /* Like Vector_append_raw, but the data is not copyied.
1722     *
1723     * Returns its success.
1724     */
1725  
1726  Global_ERWIN_EXPORT
1727  int Vector_append_vector (
1728          Vector_t *      /* self */,
1729          Vector_t const* /* other */) ATTR_NONNULL((1));
1730    /* Append a whole \p other vector at the end of the vector \p self.
1731     *
1732     * This is a frontend to Vector_insert.
1733     *
1734     * Returns its success.
1735     */
1736  
1737  Global_ERWIN_EXPORT
1738  int Vector_append_string (
1739          Vector_t*     /*self*/,
1740          oType const * /*theelements*/) ATTR_NONNULL((1));
1741    /* Like Vector_append_raw, but with a zero-terminated string instead of a
1742     * number of elements.   The null-termination will *not* be copied.
1743     *
1744     * Returns its success.
1745     */
1746  
1747  
1748  Global_ERWIN_EXPORT
1749  int Vector_make_gap (
1750          Vector_t*      /*self*/,
1751          Vector_index_t /* start_index*/,
1752          Vector_cnt_t   /* count */);
1753    /* Inserts \p count zero elements into the vector at position \p start_index.
1754     *
1755     * Returns its success.
1756     */
1757  
1758  Global_ERWIN_EXPORT
1759  int Vector_make_gap_with (
1760          Vector_t*       /*self*/,
1761          Vector_index_t  /* start_index*/,
1762          oTypeTouched    /* elem */,
1763          Vector_cnt_t    /* count */);
1764    /* Like Vector_make_gap but with a given value (which is copied for
1765     * each entry if necessary.
1766     */
1767  
1768  
1769  Global_ERWIN_EXPORT
1770  int Vector_overwrite_raw (
1771      Vector_t*     /* self*/,
1772      Vector_index_t           /* start_index_in_self */,
1773      oType const * /* newdata*/,
1774      Vector_cnt_t           /* count */);
1775    /* Overwrites portions of the vector from a normal array.
1776     * The overwritten data is freed using oType_OFREE in the old vector and
1777     * the new data copied from the new data array using oType_OCOPY.
1778     *
1779     * Returns its success.
1780     */
1781  
1782  #IFEQ(oType,oTypeVar)
1783  Global_ERWIN_EXPORT
1784  int Vector_overwrite_flags (
1785      Vector_t*           /* self */,
1786      Vector_index_t      /* start_index */,
1787      oType const *       /* values */,
1788      Vector_cnt_t        /* count */,
1789      Global_ERWIN_BOOL   /* copy_elements */,
1790      Global_ERWIN_BOOL   /* delete_overwritten_elements */);
1791    /* Like Vector_overwrite_raw but you can further specify its
1792     * (de-)allocation behaviour.
1793     *
1794     * Returns its success.
1795     */
1796  #ENDIF
1797  
1798  Global_ERWIN_EXPORT
1799  int  Vector_overwrite_string (Vector_t*     /* self*/,
1800                                       Vector_index_t           /* start_index_in_self */,
1801                                       oType const * /* newdata*/);
1802    /* Overwrites portions of the vector from a normal array.
1803     * Like Vector_overwrite_raw but with a zero-terminated string.
1804     *
1805     * Returns its success.
1806     */
1807  
1808  Global_ERWIN_EXPORT
1809  int Vector_overwrite_vector (
1810          Vector_t*     /* self*/,
1811          Vector_index_t           /* start_index_in_self */,
1812          Vector_t const* /* newdata*/);
1813    /* Overwrites portions of the vector from a vector.  Like
1814     * Vector_overwrite_raw but takes its data from another vector.
1815     *
1816     * Returns its success.
1817     */
1818  
1819  Global_ERWIN_EXPORT
1820  int  Vector_overwrite (
1821          Vector_t*         /* self*/,
1822          Vector_index_t    /* start_index_in_self */,
1823          Vector_t const*   /* newdata*/,
1824          Vector_index_t    /* start_index_in_initial */,
1825          Vector_cnt_t      /* max_count */);
1826    /* Each element is copied using Global_oType_OCOPY, the old contents are deleted
1827     * with Global_oType_OFREE.  This overwrites maximally max_count elements from
1828     * initial to self starting at position start_index_in* in the two
1829     * vectors.
1830     *
1831     * This is a frontend to Vector_overwrite_raw.
1832     *
1833     * Returns its success.
1834     */
1835  
1836  Global_ERWIN_EXPORT
1837  int  Vector_insert (
1838      Vector_t*       /* self */,
1839      Vector_index_t  /* index */,
1840      oTypeTouched    /* element */) ATTR_NONNULL((1));
1841   /* Inserts one \p element at  position \p index.
1842    *
1843    * Possible values for \p index are 0...Vector_nentries(self) both
1844    * inclusive.
1845    *
1846    * Returns its success.
1847    */
1848  
1849  Global_ERWIN_EXPORT
1850  int  Vector_insert_raw (
1851      Vector_t*       /* self */,
1852      Vector_index_t  /* index */,
1853      oType const *   /* values */,
1854      Vector_cnt_t    /* count */);
1855   /* Inserts elements from an open array whose size is given by \p count.
1856    * In all other aspects it works just like Vector_insert_vector.
1857    */
1858  
1859  Global_ERWIN_EXPORT
1860  int  Vector_insert_no_copy (
1861      Vector_t*        /* self */,
1862      Vector_index_t              /* index */,
1863      oTypeVar const * /* values */,
1864      Vector_cnt_t              /* count */);
1865    /* Like Vector_insert_raw but does not copy the given data.
1866     */
1867  
1868  Global_ERWIN_EXPORT
1869  int  Vector_insert_string (
1870          Vector_t*     /* self */,
1871          Vector_index_t           /* start_index */,
1872          oType const * /* values */) ATTR_NONNULL((1));
1873    /* Inserts a zero-terminated string into the vector.
1874     *
1875     * In all other aspects it works just like Vector_insert_vector.
1876     */
1877  
1878  Global_ERWIN_EXPORT
1879  int  Vector_insert_vector (
1880          Vector_t* /*self*/,
1881          Vector_index_t       /* start_index */,
1882          Vector_t const* /*initial*/);
1883   /*
1884    * Each element is copied using Global_oType_OCOPY.
1885    *
1886    * This is a simple frontend to Vector_make_gap and Vector_overwrite.
1887    * To insert only portions of the initial vector, use these functions
1888    * directly.
1889    *
1890    * Possible values for \p index are 0...Vector_nentries(self) both
1891    * inclusive.
1892    *
1893    * Returns its success.
1894    */
1895  
1896  
1897  Global_ERWIN_EXPORT
1898  Vector_cnt_t Vector_string_length (
1899      Vector_t const* /* self */, oType const * /* string */) ATTR_PURE;
1900    /* Find out the string length of the given zero-terminated \p string.
1901     *
1902     * The zero element is taken from the vector.  This does not modify
1903     * the vector at all, nor does it look at the vector's elements.  It
1904     * only gets the zero element from the vector.
1905     */
1906  
1907  
1908  Global_ERWIN_EXPORT
1909  int Vector_ensure_size (Vector_t * /*self*/, Vector_cnt_t /*size*/) ATTR_NONNULL((1));
1910    /* Possibly enlarges the vector by appending null elements.
1911     *
1912     * This is more than Vector_ensure_table_size, since the vector gets the given
1913     * size with zero-initialised elements at the tail if necessary.
1914     *
1915     * Returns its success.
1916     */
1917  
1918  Global_ERWIN_EXPORT
1919  int Vector_ensure_size_with (
1920      Vector_t * /*self*/, Vector_cnt_t /*size*/, oTypeTouched /*elem*/) ATTR_NONNULL((1));
1921    /* Possibly enlarges the vector by appending the given elements.
1922     *
1923     * This is similar to Vector_ensure_size, but you can define with which element
1924     * the vector will be filled when grown.
1925     *
1926     * Returns its success.
1927     */
1928  
1929  Global_ERWIN_EXPORT
1930  int Vector_set_size (Vector_t * /*self*/, Vector_cnt_t /*size*/);
1931    /* Set the vector size (by shrinking or enlarging and filling with
1932     * null elements).
1933     *
1934     * *Note* that the function will never resize the vector smaller
1935     * than Vector_MINIMAL_SIZE (actually, no function will do that).
1936     *
1937     * Returns its success.
1938     */
1939  
1940  Global_ERWIN_EXPORT
1941  int Vector_set_size_with (Vector_t * /*self*/, Vector_cnt_t /*size*/, oTypeTouched /*elem*/);
1942    /* Set the vector size (by shrinking or enlarging and filling with
1943     * the given elements).
1944     *
1945     * This is similar to Vector_set_size, but you can define with which element
1946     * the vector will be filled when grown.
1947     *
1948     * Returns its success.
1949     */
1950  
1951  Global_ERWIN_EXPORT
1952  int Vector_set_size_no_resize (Vector_t * /*self*/, Vector_cnt_t /*size*/);
1953    /* Set the vector size (by shrinking or enlarging and filling with
1954     * null elements).  When shrinking, no resizing of the table will
1955     * be done.
1956     *
1957     * Returns its success.
1958     */
1959  
1960  Global_ERWIN_EXPORT
1961  int Vector_set_size_raw (Vector_t * /*self*/, Vector_cnt_t /*size*/);
1962    /* Set the vector size by shrinking or enlarging without, resizing,
1963     * deallocation and without filling with null elements.
1964     *
1965     * This function similar to Vector_set_size_no_resize: when shrinking,
1966     * no resizing will be done.  Further, this function does not free
1967     * any elements during shrinking, so that the elements up to the
1968     * allocation size will remain in memory unmodified.  When enlarging
1969     * the vector up to the allocation size, this function will
1970     * not initialise the data.
1971     *
1972     * This function is useful if you want to temporarily hide elements
1973     * at the end of the vector.  E.g. when handling heaps where
1974     * the vector size is different from the heap size.
1975     * See Vector_make_heap.
1976     *
1977     * BE CAREFUL: if you use this function to shrink the vector, and then
1978     *             use it to enlarge the vector to a size greater than
1979     *             the original size, then there will be uninitialised
1980     *             elements.  Basic initialisation (constructor invocation)
1981     *             is performed when the vector needs to be reallocated
1982     *             to enlarged it, however.  But no null element is ever
1983     *             written by this function.
1984     *
1985     * Returns its success.
1986     */
1987  
1988  Global_ERWIN_EXPORT
1989  void Vector_shrink (Vector_t * /*self*/, Global_ERWIN_BOOL /* tight */);
1990    /* Perform a table shrink operation if necessary.  Mostly useful
1991     * if Vector_NO_AUTO_SHRINK is set, otherwise, this function is
1992     * automatically invoked whenever the vector shrinks.
1993     *
1994     * If \p tight is not Global_ERWIN_FALSE, the vector is reallocated to the
1995     * absolute minimum that is necessary to store the data.  Otherwise,
1996     * the standard algorithm of halving chunks is used.
1997     *
1998     * *Note* that the function will never resize the vector smaller
1999     * than Vector_MINIMAL_SIZE (actually, no function will do that).
2000     *
2001     * If Vector_MINIMAL_SIZE == 0, and if you invoke this function
2002     * on an empty vector, the vector will not use any allocated
2003     * internal structure anymore until you insert anything.
2004     *
2005     * When Vector_LOW_MEM is active, this functions has no operation, since the
2006     * table size cannot be changed independently from the size.
2007     *
2008     * *Note* that calling Vector_as_array() on a shrinked
2009     * vector is not wise since the vector will have to resize for
2010     * the padded zero element.
2011     *
2012     * Note: This function is always successful.  Even if realloc
2013     *       failed, the vector is still consistent.  Therefore, no
2014     *       error code is returned.  However, the error code is
2015     *       set up correctly.
2016     *
2017     * Further Note: If you defined memory overflow errors to be
2018     *       fatal (by #define Global_ERWIN_NOMEM_IS_FATAL), they are also
2019     *       fatal in this function.
2020     */
2021  
2022  Global_ERWIN_EXPORT
2023  int Vector_ensure_table_size (Vector_t * /*self*/, Vector_cnt_t /*size*/) ATTR_NONNULL((1));
2024    /* Pre-allocates vector elements.  To be used when you know some good
2025     * upper approximation to the expected number of elements which will be
2026     * inserted in the future.  Does not change the contents of the vector.
2027     *
2028     * To set a minimal size for the vector by appending zero elements,
2029     * use Vector_ensure_size.
2030     *
2031     * When Vector_LOW_MEM is active, this functions has no operation, since the
2032     * table size cannot be changed independently from the size.
2033     *
2034     * Returns its success.
2035     */
2036  
2037  Global_ERWIN_EXPORT
2038  Vector_element_ptr_t Vector_as_array (Vector_t const *);
2039    /* returns a pointer to the string the vector is stored in.  The string
2040     * is terminated with a zero element (usually Global_oType_ZERO, but this
2041     * can be changed by using Vector_new_with_zero).
2042     *
2043     * Note: For convenience, this takes a const pointer although the
2044     * representation (but not the contained data) might be changed.  It only
2045     * changes things outside the user view (behind the end of the vector).
2046     *
2047     * Further note that NULL is ok, NULL is returned, regardless of Vector_ALLOW_NULL.
2048     *
2049     * When Vector_INLINE_STORE is active, the returned pointer may become
2050     * invalid when you invoke Vector_detach or Vector_detach_as_is.  Use
2051     * Vector_as_array_detach() in that case (you cannot split that operation
2052     * in this case).
2053     *
2054     * Developer's Note: this functions is not __pure__: it may change the
2055     * internal structure, and thus the result of table_size() and
2056     * has_heap_storage() etc.
2057     */
2058  
2059  Global_ERWIN_EXPORT
2060  Vector_element_ptr_t Vector_as_open_array (Vector_t const *) ATTR_ERRNO_PURE;
2061    /* Same as Vector_as_array, but without the guaranteed zero element.
2062     * This is sometimes faster and /never/ resizes the vector.
2063     *
2064     * Note: If Vector_MINIMAL_SIZE is 0 and the vector has size 0, this
2065     *       function might return NULL instead of an allocated array!
2066     *       This is because the function will never try to reallocate.
2067     *
2068     * When Vector_INLINE_STORE is active, the returned pointer may become
2069     * invalid when you invoke Vector_detach or Vector_detach_as_is.  Use
2070     * Vector_as_array_detach() in that case (you cannot split that operation
2071     * in this case).
2072     */
2073  
2074  Global_ERWIN_EXPORT
2075  Vector_element_ptr_t Vector_as_array_detach (Vector_t *);
2076    /* Like Vector_as_array() followed by Vector_detach() with the difference
2077     * that this also works when Vector_INLINE_STORE is active.
2078     */
2079  
2080  Global_ERWIN_EXPORT
2081  void Vector_ensure_heap_storage (Vector_t *) ATTR_NONNULL((1));
2082    /* Ensure that the contents are stored on the heap so that _detach
2083     * does not destroy the vector.  Used by Vector_as_array_detach(), but
2084     * may also be used manually before as_array() or Vector_nth_ptr() to
2085     * ensure that the pointer is on the heap.
2086     *
2087     * This function actually does something only when Vector_INLINE_STORE
2088     * is used or Vector_MINIMAL_SIZE is 0.  Otherwise, this function does
2089     * nothing.  This includes not doing any harm.
2090     *
2091     * Note: With both LOW_MEM and INLINE_STORE active, this functions may
2092     *       append ZERO elements to the vector, because resizing the table
2093     *       may mean to resize the vector.
2094     *
2095     * Note: With Vector_MINIMAL_SIZE == 0, vectors of size 0 are still *not*
2096     *       resized to size 1.
2097     *       Functions returning pointers to the table (e.g. Vector_as_open_array)
2098     *       will return NULL in this special case, which is ususally no problem
2099     *       in handling.
2100     *       This function is for handling the more complex cases that occur with
2101     *       the Vector_INLINE_STORE option.
2102     */
2103  
2104  Global_ERWIN_EXPORT
2105  Global_ERWIN_BOOL Vector_has_heap_storage (Vector_t const *) ATTR_PURE;
2106    /* Returns whether the storage on the heap is allocated or not.
2107     * This is interesting only when Vector_MINIMIAL_SIZE == 0 or
2108     * Vector_INLINE_STORE is activated.
2109     */
2110  
2111  Global_ERWIN_EXPORT
2112  Vector_cnt_t Vector_inline_store_cnt (void) ATTR_PURE;
2113    /* Returns the number of elements the inline store has.
2114     * This is 0 unless Vector_INLINE_STORE is activated, in which case other
2115     * values are possible.  The result is a constant, therefore there is no
2116     * argument to this function.
2117     */
2118  
2119  Global_ERWIN_EXPORT
2120  Vector_element_ptr_t Vector_as_open_array_detach (Vector_t *);
2121    /* Like Vector_as_open_array() followed by Vector_detach() with the difference
2122     * that this also works when Vector_INLINE_STORE is active.
2123     */
2124  
2125  Global_ERWIN_EXPORT
2126  void Vector_qsort (Vector_t *, Vector_cmp_t /*order*/);
2127    /* Uses the \p order function to sort the vector.  The compare function may be NULL
2128     * if Global_oType_CMP is defined.  In this case that default compare function
2129     * is used.  See Vector_u.h for definition.
2130     *
2131     * For a stable sort function, see Vector_sort.
2132     *
2133     * For a guaranteed O(n log n) runtime and O(1) space, see Vector_heap_sort.
2134     *
2135     * The default cmp function, used if cmp is NULL, is Global_oType_CMP.
2136     *
2137     * This function the CLib function qsort(3).   Note that qsort(3) need not
2138     * use Quicksort internally, e.g. if the glibc under Linux finds that there
2139     * is enough memory, it uses merge sort instead.  So you have good chances
2140     * that this function is stable *in many cases under Linux*.  However, if you
2141     * need stability, this function does not guarantee that.  Especially, when
2142     * running your programm under Windows, its qsort(3) implementation is *not*
2143     * stable.  That's perfectly ok.  For stability, simply always use
2144     * Vector_sort().
2145     *
2146     * In sorted vectors, you can find entries in O(log n) vector using
2147     * Vector_bfind or Vector_locate.
2148     */
2149  
2150  Global_ERWIN_EXPORT
2151  void Vector_sort (Vector_t *, Vector_cmp_t /*order*/);
2152    /* Uses Global_erwin_merge_sort, which implements a stable sorting algorithm.
2153     * Uses the \p order function. \p order may be NULL (see Vector_qsort and
2154     * Vector_heap_sort) if Global_oType_CMP is defined, which will then be used.
2155     *
2156     * The default cmp function, used if cmp is NULL, is Global_oType_CMP.
2157     *
2158     * Uses Erwin's erwin_merge_sort function which is stable but needs O(n) space.
2159     *
2160     * You can find entries in a sorted vector using Vector_bfind or Vector_locate.
2161     */
2162  
2163  Global_ERWIN_EXPORT
2164  Vector_index_t Vector_bfind (Vector_t const *, oTypeParam, Vector_cmp_t);
2165    /* Needs a sorted vector.  Then searches with binary search.  Uses the cmp function.
2166     * cmp may be NULL (see above)
2167     * -1 means: not found.
2168     *
2169     * Uses the system function bsearch().
2170     *
2171     * This operation takes O(log n) time.
2172     *
2173     * The default cmp function, used if cmp is NULL, is Global_oType_CMP.
2174     *
2175     * This function checks the input when in debug mode, causing assertion
2176     * failures if input is not sorted.the heap property is violated after operation.
2177     * Note that this check takes O(n) time, so the function is significantly
2178     * slower during debugging.  If you don't want this, you may
2179     *
2180     *    #define Vector_DEBUG_EXPENSIVE_CHECKS        0
2181     * or #define Global_VECTOR_DEBUG_EXPENSIVE_CHECKS 0   (for all vectors)
2182     *
2183     * References
2184     * ~~~~~~~~~~
2185     * Vector_qsort, Vector_sort, Vector_locate, Vector_find.
2186     */
2187  
2188  Global_ERWIN_EXPORT
2189  Global_ERWIN_BOOL Vector_locate (
2190      Vector_index_t * /*index*/,
2191      Vector_t const * /*self*/,
2192      oTypeParam /*needle*/,
2193      Vector_cmp_t /*order*/,
2194      int /* how */);
2195    /* Needs a sorted vector.   Then searches with binary search.  Uses the cmp function.
2196     * cmp may be NULL (see above)
2197     *
2198     * In contrast to Vector_bfind you are provided with a possible
2199     * insertion position that will keep the vector's order.
2200     *
2201     * The function returns Global_ERWIN_TRUE if the element was found and Global_ERWIN_FALSE if not.
2202     *
2203     * This operation takes O(log n) time.
2204     *
2205     * The default cmp function, used if cmp is NULL, is Global_oType_CMP.
2206     *
2207     * This function checks the input when in debug mode, causing assertion
2208     * failures if input is not sorted.the heap property is violated after operation.
2209     * Chis check takes O(n) time, so the function is significantly slower
2210     * during debugging.  If you don't want this, you may
2211     *
2212     *    #define Vector_DEBUG_EXPENSIVE_CHECKS        0
2213     * or #define Global_VECTOR_DEBUG_EXPENSIVE_CHECKS 0   (for all vectors)
2214     *
2215     * The \p how argument defines what value to return for the *\p index.  The following table
2216     * give an explanation of the value written into *\p index:
2217     *
2218     *   +---------+------------------------+------------------------+-----------------------+
2219     *   |! \p how |! if found (result ==   |! if not found (result  |! usage                |
2220     *   |         |  Global_ERWIN_TRUE)    |  == Global_ERWIN_FALSE |                       |
2221     *   +---------+------------------------+------------------------+-----------------------+
2222     *   | -1      | the smallest index     | insertion position     | to find an element or |
2223     *   |         | of equal elements      |                        | to insert an element  |
2224     *   |         |                        |                        | at the smallest       |
2225     *   |         |                        |                        | possible position     |
2226     *   +---------+------------------------+------------------------+-----------------------+
2227     *   | 0       | some index of an equal | insertion position     | to find and insert    |
2228     *   |         | element                |                        | without caring about  |
2229     *   |         |                        |                        | order of equal        |
2230     *   |         |                        |                        | elements              |
2231     *   +---------+------------------------+------------------------+-----------------------+
2232     *   | 1       | the largest index of   | insertion position - 1 | to find an element or |
2233     *   |         | equal elements         |                        | to insert an element  |
2234     *   |         |                        |                        | at the largest        |
2235     *   |         |                        |                        | possible position.    |
2236     *   +---------+------------------------+------------------------+-----------------------+
2237     *
2238     * At first sight, for \p how==1 the value of \p index seems strange.  But from the point of
2239     * view of inserting even in case of equality, you can simply insert at (*\p index+1) to
2240     * insert at the right most possible position keeping the vector's order without looking at
2241     * the function's return value.  However, in case of finding the element, *\p index always
2242     * points to an equal element.  Note that because of this, \p index may be -1 (for \p how=1
2243     * if you want to insert at the beginning).
2244     *
2245     * Note: for \p how==0 and \p how==-1, the functions will set *\p index to
2246     * Vector_nentries(self) if the searched element is larger than any in the vector,
2247     * because that is the correct value for Vector_insert.
2248     *
2249     * Summarized constraints that always hold:
2250     *
2251     *    +-------------------------------------+------------------------------------------+
2252     *    | for \p how==0 and \p how==-1        | *\p index always is the correct          |
2253     *    |                                     | insertion position.                      |
2254     *    +-------------------------------------+------------------------------------------+
2255     *    | for \p how==1                       | (*\p index + 1) always is the correct    |
2256     *    |                                     | insert position.                         |
2257     *    +-------------------------------------+------------------------------------------+
2258     *    | if the return value is              | *\p index points to an equal element.    |
2259     *    | Global_ERWIN_TRUE                   |                                          |
2260     *    +-------------------------------------+------------------------------------------+
2261     *
2262     * References
2263     * ~~~~~~~~~~
2264     * Vector_qsort, Vector_sort, Vector_bfind.
2265     */
2266  
2267  /* ***** iteration: ***** */
2268  /* New approach: */
2269  #define Vector_forall(v,i,h) \
2270          for(Vector_init_iterator((v),&(i)); \
2271              Vector_next_iteration((v),&(i),&(h)); /*nix*/)
2272  /* Iteration operator for vectors.  Iterates over all indices and values starting at index 0
2273   * and incrementing \p i by 1 in each iteration. In constrast to maps, you do not need an
2274   * iterator (the index is used as an iterator).
2275   *
2276   * In C++, use vector_forall.
2277   *
2278   * Iterators are nestable without restriction (even on the same vector).
2279   * During iteration, the vector may not be changed.
2280   * If you use C++, the *_copy and *_sorted iterators allow changing during iteration.
2281   *
2282   * You may freely use break and continue in the loop.
2283   *
2284   * : int i;
2285   * : char *s;
2286   * : vector_char_p_forall (v, i, s) {
2287   * :     printf ("v[%d]=%s\n", i, s);
2288   * : }
2289   */
2290  
2291  #define Vector_forall_ptr(v,i,h) for(Vector_init_iterator(v,&(i)); Vector_next_iteration_ptr(v,&(i),&(h)); /*nix*/)
2292  /* Iteration operator for vectors.  Iterates over all indices and pointers to values starting at
2293   * index 0.  In contrast to Vector_forall this macro can be used to change the values due to
2294   * the pointer iteration. */
2295  
2296  #define Vector_forall_ptr_const(v,i,h) for(Vector_init_iterator(v,&(i)); Vector_next_iteration_ptr_const(v,&(i),&(h)); /*nix*/)
2297  
2298  #define Vector_forall_reverse(v,i,h) for(Vector_init_iterator_reverse(v,&(i)); Vector_next_iteration_reverse(v,&(i),&(h)); /*nix*/)
2299  /* Iterator operator for reversed order, i.e., starting at index Vector_nentries()-1 and
2300   * decrementing \p i downto 0.  See Vector_forall for details.
2301   */
2302  
2303  #define Vector_forall_ptr_reverse(v,i,h) for(Vector_init_iterator_reverse(v,&(i)); Vector_next_iteration_ptr_reverse(v,&(i),&(h)); /*nix*/)
2304  /* Iterator operator for reversed order, i.e., starting at index Vector_nentries()-1 and
2305   * decrementing \p i downto 0.  See Vector_forall, Vector_forall_reverse and
2306   * Vector_forall_ptr for details.
2307   */
2308  
2309  #define Vector_forall_ptr_const_reverse(v,i,h) for(Vector_init_iterator_reverse(v,&(i)); Vector_next_iteration_ptr_const_reverse(v,&(i),&(h)); /*nix*/)
2310  
2311  Global_ERWIN_EXPORT
2312  void Vector_init_iterator (Vector_t const *, Vector_index_t * /*keyptr*/);
2313  /*private*/
2314  
2315  Global_ERWIN_EXPORT
2316  Global_ERWIN_BOOL Vector_next_iteration  (Vector_t const *, Vector_index_t * /*keyptr*/, oType * /*valueptr*/);
2317  /*private*/
2318  
2319  Global_ERWIN_EXPORT
2320  Global_ERWIN_BOOL Vector_next_iteration_ptr  (Vector_t *, Vector_index_t * /*keyptr*/, oTypeVar ** /*valuepp*/);
2321  /*private*/
2322  
2323  Global_ERWIN_EXPORT
2324  Global_ERWIN_BOOL Vector_next_iteration_ptr_const  (Vector_t const *, Vector_index_t * /*keyptr*/, oTypeVar const ** /*valuepp*/);
2325  /*private*/
2326  
2327  Global_ERWIN_EXPORT
2328  void Vector_init_iterator_reverse (Vector_t const *, Vector_index_t * /*keyptr*/);
2329  /*private*/
2330  
2331  Global_ERWIN_EXPORT
2332  Global_ERWIN_BOOL Vector_next_iteration_reverse  (Vector_t const *, Vector_index_t * /*keyptr*/, oType * /*valueptr*/);
2333  /*private*/
2334  
2335  Global_ERWIN_EXPORT
2336  Global_ERWIN_BOOL Vector_next_iteration_ptr_reverse  (Vector_t *, Vector_index_t * /*keyptr*/, oTypeVar ** /*valueptr*/);
2337  /*private*/
2338  
2339  Global_ERWIN_EXPORT
2340  Global_ERWIN_BOOL Vector_next_iteration_ptr_const_reverse  (Vector_t const *, Vector_index_t * /*keyptr*/, oTypeVar const ** /*valueptr*/);
2341  /*private*/
2342  
2343  /* ***** access to all entries: ***** */
2344  Global_ERWIN_EXPORT
2345  void Vector_clear (Vector_t* /*self*/);
2346     /* Like Vector_erase for all elements. */
2347  
2348  Global_ERWIN_EXPORT
2349  void Vector_clear_keep (Vector_t* /*self*/, Vector_cnt_t /*table_min_size*/);
2350     /* Like Vector_clear(), but the internal table is not shrunk below
2351      * the given minimal size (instead of the predefined minimal table size)
2352      */
2353  
2354  #IFEQ(oType,oTypeVar)
2355  Global_ERWIN_EXPORT
2356  void Vector_clear_flags (Vector_t* /*self*/, Global_ERWIN_BOOL /* resize */, Global_ERWIN_BOOL /* delete_elems */);
2357     /* Like Vector_clear you can specify whether a realloc will be performed and
2358      * whether the elements will be freed.
2359      * The former is useful if you  want to clear the vector but expect new data of
2360      * around the same length to be inserted afterwards.
2361      *
2362      * This function is only available of oType == oTypeVar.
2363      */
2364  #ENDIF
2365  
2366  Global_ERWIN_EXPORT
2367  void Vector_clear_no_resize (Vector_t* /*self*/);
2368     /* Compatibility & convenience:
2369      * Like Vector_clear(\p self) without resizing the table.
2370      */
2371  
2372  /*BEGIN:IGNORE*/
2373  #if defined(Global_ERWIN_COMPILING) || !defined(NDEBUG)
2374  /*END:IGNORE*/
2375  
2376  Global_ERWIN_EXPORT
2377  Vector_cnt_t Vector_nentries (Vector_t const * /*self*/) ATTR_PURE;
2378     /* Returns the number of entries in the vector.
2379      *
2380      * Note: This is not called `Vector_size' in order to prevent confusion
2381      * about the unit of the result.  `size' might refer to bytes.  `nentries', however,
2382      * is clearer.
2383      */
2384  
2385  Global_ERWIN_EXPORT
2386  Global_ERWIN_BOOL Vector_empty (Vector_t const * /*self*/) ATTR_PURE;
2387     /* Returns whether the vector contains no elements. */
2388  
2389  /*BEGIN:IGNORE*/
2390  /* #if defined(Global_ERWIN_COMPILING) || Vector_ALLOW_OUTOFRANGE || Vector_RANGE_CHECK */
2391  #else
2392  #define Vector_INLINE__NENTRIES
2393  #endif
2394  /*END:IGNORE*/
2395  
2396  Global_ERWIN_EXPORT
2397  Vector_cnt_t Vector_table_size (Vector_t const* /*self*/) ATTR_PURE;
2398    /* For debugging and optimisation purposes (use rarely): the current
2399     * size of of the internal pre-allocated array of elements.
2400     */
2401  
2402  
2403  Global_ERWIN_EXPORT
2404  Vector_index_t Vector_find  (
2405      Vector_t const * /*self*/, Vector_index_t /*start*/, oTypeParam /*needle*/) ATTR_ERRNO_PURE;
2406     /* Tries to finds an entry equal to needle.  Returns the index of the first element >= start
2407      * or -1 of nothing was found.  The search is performed from the beginning to the end.
2408      *
2409      * If start is negativ, search is started at the last but start-th position.  So to search
2410      * the whole vector, start should be 0.
2411      *
2412      * Note: This function is not called `Vector_search', because it does not only
2413      * perform the search, but also returns the result of that search.
2414      *
2415      * References
2416      * ~~~~~~~~~~
2417      * Vector_rfind, Vector_bfind.
2418      */
2419  
2420  Global_ERWIN_EXPORT
2421  Vector_element_ptr_t Vector_find_ptr (
2422     Vector_t const * /*self*/, Vector_index_t /*start*/, oTypeParam /*needle*/) ATTR_ERRNO_PURE;
2423     /* Like Vector_find but returns a pointer to the found item or NULL on failure. */
2424  
2425  Global_ERWIN_EXPORT
2426  Vector_index_t Vector_rfind (
2427      Vector_t const * /*self*/, Vector_index_t /*start*/, oTypeParam /*needle*/) ATTR_ERRNO_PURE;
2428     /* Tries to finds an entry equal to needle.  Returns the index of the first element <= start
2429      * or -1 of nothing was found.  The search is performed from the end to the beginning.
2430      *
2431      * If start is negativ, search is started at the last but start-th position.  So to search
2432      * the whole vector, start should be -1.
2433      *
2434      * References
2435      * ~~~~~~~~~~
2436      * Vector_find
2437      */
2438  
2439  Global_ERWIN_EXPORT
2440  Vector_element_ptr_t Vector_rfind_ptr (
2441      Vector_t const * /*self*/, Vector_index_t /*start*/, oTypeParam /*needle*/) ATTR_ERRNO_PURE;
2442     /* Like Vector_rfind but returns a pointer to the found item or NULL on failure. */
2443  
2444  Global_ERWIN_EXPORT
2445  Vector_index_t Vector_find_raw (
2446          Vector_t const * /*self*/,
2447          Vector_index_t /*start*/,
2448          oType const * /*needle*/,
2449          Vector_cnt_t /*len*/) ATTR_ERRNO_PURE;
2450     /* Like Vector_find but tries to find equal parts.  See Vector_rfind_raw. */
2451  
2452  Global_ERWIN_EXPORT
2453  Vector_index_t Vector_rfind_raw (Vector_t const * /*self*/, Vector_index_t /*start*/,
2454                              oType const * /*needle*/, Vector_cnt_t /*len*/) ATTR_ERRNO_PURE;
2455     /* Like Vector_rfind but tries to find equal parts.
2456      *
2457      * Return the position of `needle' or -1 if it is not found.
2458      * Note that it is no problem to search for the zero element Global_oType_ZERO.
2459      * These all use the Vector_EQUAL macro.
2460      *
2461      * Negative values for start will count from the end of the vector.
2462      */
2463  
2464  Global_ERWIN_EXPORT
2465  Vector_index_t Vector_find_if (
2466          Vector_t const * /*self*/,
2467          Vector_index_t /* start*/,
2468          Vector_feature_t /*feature*/,
2469          Global_ERWIN_BOOL /* value */);
2470     /* find_if behaves like position-if in CommonLisp.
2471      *
2472      * Tries to find an entry with a certain feature.  Returns the index of the first element >= start
2473      * or -1 of nothing was found.  The search is performed from the beginning to the end.
2474      *
2475      * If start is negativ, search is started at the last but start-th position.  So to search
2476      * the whole vector, start should be 0.
2477      */
2478  
2479  Global_ERWIN_EXPORT
2480  Vector_index_t Vector_rfind_if (
2481          Vector_t const * /*self*/,
2482          Vector_index_t /* start */,
2483          Vector_feature_t /*feature*/,
2484          Global_ERWIN_BOOL /* value */);
2485     /* Tries to find an entry with a certain feature.  Returns the index of the first element <= start
2486      * or -1 of nothing was found.  The search is performed from the end to the beginning.
2487      *
2488      * If start is negativ, search is started at the last but start-th position. So to search
2489      * the whole vector, start should be -1.
2490      */
2491  
2492  
2493  Global_ERWIN_EXPORT
2494  Global_ERWIN_BOOL Vector_is_equal_at (Vector_t const * /*self*/,  Vector_index_t /*pos*/,
2495                                  oType const * /*other*/, Vector_cnt_t /*len*/) ATTR_ERRNO_PURE;
2496     /* Checks whether the given string is found at the given position.
2497      * Negative values for pos will count from the end of the vector.
2498      */
2499  
2500  Global_ERWIN_EXPORT
2501  void Vector_ltrim_if (Vector_t * /*self*/, Vector_feature_t /*feature*/, Global_ERWIN_BOOL /*value*/);
2502     /* Cuts off all elements that have the `feature' from the left of the vector
2503      *
2504      * References: Vector_rtrim_if, Vector_trim_if
2505      */
2506  
2507  Global_ERWIN_EXPORT
2508  void Vector_rtrim_if (Vector_t * /*self*/, Vector_feature_t /*feature*/, Global_ERWIN_BOOL /*value*/);
2509     /* Cuts off all elements that have the `feature' from the right of the vector
2510      *
2511      * References: Vector_ltrim_if, Vector_trim_if
2512      */
2513  
2514  Global_ERWIN_EXPORT
2515  void Vector_trim_if  (Vector_t * /*self*/, Vector_feature_t /*feature*/, Global_ERWIN_BOOL /*value*/);
2516     /* Cuts off all elements that have the `feature' from the left and right of the vector
2517      *
2518      * References: Vector_ltrim_if, Vector_rtrim_if
2519      */
2520  
2521  Global_ERWIN_EXPORT
2522  void Vector_map (Vector_t * /*self*/, Vector_map_t /*map*/);
2523     /* Applies a given function to all elements of the vector. */
2524  
2525  Global_ERWIN_EXPORT
2526  int Vector_cmp (Vector_t const *, Vector_t const *, Vector_cmp_t /*cmp*/);
2527      /* Returns a comparison value for lexical sort order, or by length order,
2528       * depending on Vector_COMPARE_LEXICOGRAPHICALLY, which defaults to 1 for
2529       * non-character types, and to 0 for all others.  The difference is that
2530       * the length order checks the length of the vector first, which is expected
2531       * to yield a quicker distinction for most vectors.
2532       *
2533       * This function is NULL safe.  NULL is smaller than any
2534       * other vector.  By this you can easily sort a vector in reverse order and then
2535       * rtrim_if(is_NULL) to get rid of NULL elements.
2536       *
2537       * If cmp is NULL, Global_oType_CMP will be used.  If that is not defined, an error
2538       * will occur.
2539       */
2540  
2541  Global_ERWIN_EXPORT
2542  Global_hashval_t Vector_hash_raw (Vector_t const *) ATTR_ERRNO_PURE;
2543      /* Returns a hash value, which is derived from hash values for oType.
2544       *
2545       * This is traditionally called hash_raw although the hash value is
2546       * good enough for a normal HASH nowadays.
2547       *
2548       * Note: Usually you want hash values if you work with maps.  So you
2549       *       should define the hash value in such a way that both the map
2550       *       header as well as the vector header find them.
2551       *
2552       * Further Note: This will only be implemented if Global_oType_HASH_RAW
2553       * is defined.
2554       *
2555       */
2556  
2557  ERWIN_WRAPPER
2558  Global_hashval_t Vector_hash (Vector_t const *) ATTR_ERRNO_PURE;
2559      /* Same as Vector_hash_raw() now that hash_raw() is good enough. */
2560  
2561  ERWIN_WRAPPER
2562  Global_hashval_t Vector_hash (Vector_t const *x)
2563  {
2564      return Vector_hash_raw(x);
2565  }
2566  
2567  #IFEQ (isChar,1)
2568  
2569  Global_ERWIN_EXPORT
2570  int Vector_fread (Vector_t * /*self*/, FILE * /*f*/, Vector_cnt_t /* max_count */);
2571     /* Read the whole file or a prefix into the vector.
2572      * If you pass -1 for max_count, there is no maximal count.
2573      *
2574      * This function returns the number of elements read or -1 in case of
2575      * an error.  If vector_errno is VECTOR_ERR_IO, you can use ferror(f)
2576      * to query the error.
2577      */
2578  
2579  Global_ERWIN_EXPORT
2580  int Vector_fgets (Vector_t * /*self*/, FILE * /*f*/, Vector_cnt_t /* max_count */);
2581     /* Read one line into the vector.  You can bound the number of elements stored
2582      * in the vector.  However, a line is always read completely to the end.
2583      *
2584      * This function returns the error code.  VECTOR_OK means no error.
2585      *
2586      * If no char could be read, this returns VECTOR_WARN_EMPTY.  Otherwise,
2587      * VECTOR_OK is returned if not file error occured, VECTOR_ERR_IO
2588      * otherwise.  Then you can query the error on the file using ferror (f).
2589      *
2590      * Like the clib function, the trailing \n is appended if it was there.
2591      */
2592  
2593  /* Note: Clean writing is easier, so that functions for that are not
2594   *       provided. */
2595  
2596  Global_ERWIN_EXPORT
2597  void Vector_ltrim (Vector_t * /*self*/);
2598     /* See Vector_trim.
2599      */
2600  
2601  Global_ERWIN_EXPORT
2602  void Vector_rtrim (Vector_t * /*self*/);
2603     /* See Vector_trim.
2604      */
2605  
2606  Global_ERWIN_EXPORT
2607  void Vector_trim  (Vector_t * /*self*/);
2608     /* Like the Vector_trim_if family with an isspace feature.  The special isspace used
2609      * here defines '\0' to be a space.  This is useful for pre-allocating space
2610      * by inserting \0, then using standard clib functions to fill the buffer,
2611      * and then trimming it.
2612      */
2613  
2614  Global_ERWIN_EXPORT
2615  void Vector_chomp (Vector_t * /*self*/);
2616     /* Like Vector_rtrim with ((X) == '\n' || (X) == '\r') feature
2617      */
2618  
2619  Global_ERWIN_EXPORT
2620  void Vector_to_upper (Vector_t * /*self*/);
2621     /* Translates all elements using the Global_erwin_to_upper function.
2622      */
2623  
2624  Global_ERWIN_EXPORT
2625  void Vector_to_lower (Vector_t * /*self*/);
2626     /* Translates all elements using the Global_erwin_to_lower function.
2627      */
2628  
2629  Global_ERWIN_EXPORT
2630  Vector_index_t Vector_basename_index (Vector_t const * /*self*/) ATTR_ERRNO_PURE;
2631     /* NOTE: This function is obsolete and left in for compatibility reasons.
2632      * Use Vector_basename_range instead.
2633      *
2634      * Returns the index of the first character that belongs to the basename of a
2635      * file name.  The algorithm depends on the operating system this runs on.
2636      *
2637      * E.g. under Unix, for "/tmp/test///" this function returns 5.  To get the
2638      * length of the basename, use Vector_basename_range.
2639      */
2640  
2641  Global_ERWIN_EXPORT
2642  void Vector_basename_range (Vector_index_t * /*first*/, Vector_cnt_t * /*length*/, Vector_t const * /*self*/);
2643     /* Returns the index of the first and last characters that belongs to the basename
2644      * of a file name.  The algorithm depends on the operating system this runs on.
2645      *
2646      * This is an extended version of Vector_basename_index, which does not return
2647      * the last index.  E.g. under Unix, for "/tmp/test///" this function returns:
2648      *     *first=  5,
2649      *     *length= 4
2650      *
2651      * first and length may be NULL in which case nothing is returned for the
2652      * respective value.
2653      */
2654  
2655  Global_ERWIN_EXPORT
2656  int Vector_append_directory (Vector_t * /*self*/, Vector_t const * /*path*/);
2657     /* Append the directory of path to self.  This appended string includes the
2658      * path separator if necessary.  Returns Global_vector_errno.
2659      */
2660  
2661  Global_ERWIN_EXPORT
2662  int Vector_append_basename (Vector_t * /*self*/, Vector_t const * /*path*/);
2663     /* Append the base name of path to self.  This appended string does not include
2664      * any path separator.  Returns Global_vector_errno.
2665      */
2666  
2667  Global_ERWIN_EXPORT
2668  int Vector_append_config_file_name (
2669          Vector_t *   /*self*/,
2670          oType const * /*program_name*/,
2671          Global_ERWIN_BOOL         /*local*/);
2672     /* Append the default configuration file name (either global or local one) to the vector.
2673      * The default global name under Unix is
2674      *    : /etc/progname.conf
2675      * under Windos it is
2676      *    : C:\etc\progname.ini
2677      *
2678      * The default local name under Unix is
2679      *    : $HOME/.prognamerc
2680      * under Windos
2681      *    : %HOME%\progname.ini
2682      *
2683      * Returns Global_vector_errno.  Note that if $HOME is not defined (which is typical under DOS),
2684      * VECTOR_ERR_OUTOFRANGE is returned and nothing appended if local != 0.
2685      */
2686  
2687  #if Vector_NO_FORMAT == 0
2688  
2689  #ifdef HAVE_STDARG_H
2690  #  include <stdarg.h>
2691  #endif
2692  
2693  /*
2694   * Format options for the oformat family
2695   */
2696  #if !defined(Global_FO_QUOTE_C_STRING)
2697  
2698  /*! enum: Global_FO_* */
2699  #define Global_FO_NO_QUOTE            0UL
2700    /* Format option for Vector_o_format family: perform no quotation on %s strings.
2701     * This is the default.
2702     *
2703     * The NULL pointer is printed as (null).
2704     */
2705  #define Global_FO_QUOTE_C_STRING      1UL
2706  #define Global_FO_QUOTE_PERL_STRING   1UL
2707    /* Format option for Vector_oformat family: quote all %s strings for a C compiler.
2708     * There is another option Global_FO_QUOTE_IN_C_STRING which does not output
2709     * the surrounding "" of the string.
2710     *
2711     * The NULL pointer is printed as NULL.
2712     */
2713  
2714  #define Global_FO_QUOTE_IN_C_STRING    2UL
2715  #define Global_FO_QUOTE_IN_PERL_STRING 2UL
2716    /* Format option for Vector_oformat family: quote all %s strings for a C compiler,
2717     * assume that we are inside a string and do not output the embracing "".  With the
2718     * surrounding "", use the Global_FO_QUOTE_C_STRING option.
2719     *
2720     * The NULL pointer is printed as the empty string.
2721     */
2722  
2723  #define Global_FO_QUOTE_BOURNE_SHELL  3UL
2724    /* Format option for Vector_oformat family: quote all %s strings for a Bourne shell.
2725     *
2726     * The NULL pointer produces an out of range error.
2727     */
2728  
2729  #define Global_FO_QUOTE_FORMAT        4UL
2730    /* Format option for Vector_oformat family: quote all %s strings for fprintf command.
2731     *
2732     * Note: Usually the C compiler reads a format string first, so you are likely
2733     *       to quote again for a C compiler with Global_FO_QUOTE_C_STRING
2734     *
2735     * The NULL pointer produces an out of range error.
2736     */
2737  
2738  #define Global_FO_QUOTE_WIN_SHELL     5UL
2739    /* Format option for Vector_oformat family: quote all %s strings for a Windows shell.
2740     *
2741     * The NULL pointer produces an out of range error.
2742     */
2743  
2744  #define Global_FO_QUOTE_LISP_STRING   6UL
2745    /* Format option for Vector_oformat family: quote all %s strings in CommonLisp syntax.
2746     *
2747     * The NULL pointer is printed as nil.
2748     */
2749  
2750  #define Global_FO_QUOTE_IN_LISP_STRING  7UL
2751    /* Format option for Vector_oformat family: quote all %s strings in CommonLisp
2752     * syntax.  Do not output the embracing "".  See Global_FO_QUOTE_LISP_STRING.
2753     *
2754     * The NULL pointer is printed as the empty string.
2755     */
2756  
2757  #define Global_FO_QUOTE_URL           8UL
2758    /* Format option for Vector_oformat family: quote all %s strings for
2759     * using in an URL. */
2760  
2761  #define Global_FO_QUOTE_HTML          9UL
2762  #define Global_FO_QUOTE_XML           9UL
2763  #define Global_FO_QUOTE_SGML          9UL
2764    /* Format option for Vector_oformat family: quote all %s strings for
2765     * in HTML syntax (no charset conversion is done, so if you pass char*,
2766     * this is iso-8859-1 in HTML and XML, while in SGML, it is whatever
2767     * you declared).  This is suitable for HTML,XML, and SGML -- we do
2768     * not assume any named entities.  (Not even &lt; &gt; and &amp;).
2769     * Anything else is quoted in decimal for maximum compatibility.
2770     */
2771  
2772  /* FIXME: Have base64 and quoted-printable, too. */
2773  #define Global_FO_QUOTE_RESERVED3    10UL
2774  #define Global_FO_QUOTE_RESERVED2    11UL
2775  #define Global_FO_QUOTE_RESERVED1    12UL
2776  
2777  #define Global_FO_QUOTE_USER1        13UL
2778    /* Format option for Vector_oformat family: user defined %s quotation method no. 1 */
2779  
2780  #define Global_FO_QUOTE_USER2        14UL
2781    /* Format option for Vector_oformat family: user defined %s quotation method no. 2 */
2782  
2783  #define Global_FO_QUOTE_USER3        15UL
2784    /* Format option for Vector_oformat family: user defined %s quotation method no. 3 */
2785  
2786  #define Global_FO_QUOTE_USER_MIN   Global_FO_QUOTE_USER1
2787  #define Global_FO_QUOTE_USER_MAX   Global_FO_QUOTE_USER3
2788  
2789  /* 4 bits -> 4 bits */
2790  #define Global_FO_QUOTE_MASK       15UL
2791  #ifdef ERWIN_DOS
2792  #    define Global_FO_QUOTE_SHELL Global_FO_QUOTE_WIN_SHELL
2793    /* Format option for Vector_oformat family: depending on the operating system you compiled
2794     * for, this is either equal to Global_FO_QUOTE_BOURNE_SHELL or
2795     * Global_FO_QUOTE_WIN_SHELL. */
2796  
2797  #else
2798  #    define Global_FO_QUOTE_SHELL Global_FO_QUOTE_BOURNE_SHELL
2799  #endif /* ERWIN_DOS */
2800  
2801  #define Global_FO_VOID_P            0UL   /* default: %p reads a normal pointer */
2802  #define Global_FO_VECTOR           16UL
2803  /* Instead of reading a normal pointer, %p reads a Vector_t *.
2804   */
2805  
2806  #define Global_FO_S_TYPE_MASK      16UL
2807  
2808  /* 1 bit -> +4 = 5 bits */
2809  #define Global_FO_NO_CENTER         0UL   /* default: right adjusted, with `-' left adjusted */
2810  #define Global_FO_CENTER           32UL
2811   /* Format option for Vector_oformat family:
2812    * Center the string.  The `-' format specifier then determines whether to tend to
2813    * center to the left or to the right when it is not possible to center perfectly.
2814    */
2815  
2816  /* 1 bit  -> +5 = 6 bits */
2817  #define Global_FO_RADIX_DEFAULT     0UL   /* default: 10 or 16 for %x. */
2818  #define Global_FO_RADIX_SHIFT       6UL
2819  #define Global_FO_RADIX_MASK      127UL
2820  #define Global_FO_RADIX(RADIX)   ((((unsigned long)(RADIX)) & Global_FO_RADIX_MASK) << Global_FO_RADIX_SHIFT)
2821   /* Format option for Vector_oformat family: specify a radix for numbers.  With printf,
2822    * only 8, 10, 16 are possible (via the %o, %d and %x formats resp.).  This allows
2823    * you to specify a different radix.
2824    *
2825    * For integers, you may use a format specifier character to set base, casing in
2826    * a few cases, in which case their variant printing form will be used:
2827    *
2828    *     Global_FO_RADIX('d')  - base = 10                   - like %d   - "10"
2829    *     Global_FO_RADIX('x')  - base = 16, lowcase, variant - like %#x  - "0xa"
2830    *     Global_FO_RADIX('X')  - base = 16, upcase,  variant - like %#X  - "0XA"
2831    *     Global_FO_RADIX('o')  - base = 8,           variant - like %#o  - "012"
2832    *     Global_FO_RADIX('b')  - base = 2,  lowcase, variant             - "0b1010"
2833    *     Global_FO_RADIX('B')  - base = 2,  upcase,  variant             - "0B1010"
2834    *
2835    * Of course, 'b' and 'B' are not format specifiers but are provided
2836    * for convenience.
2837    *
2838    * Other radix values > 64 are undefined.  (Values <= 64 will be treated
2839    * as numeric, e.g. ASCII '@' will select base64 digits.)
2840    *
2841    * This does *not* change the handling of the sign: %d is signed by default
2842    * and %u,%x,%o are unsigned.
2843    *
2844    * For floats, the Global_FO_RADIX setting overrides the format specifier.
2845    * In contrast to integers, the variant form is not selected when using the
2846    * base to set the format specifier.
2847    * You may use:
2848    *
2849    *     Global_FO_RADIX('e')  - %e
2850    *     Global_FO_RADIX('E')  - %E
2851    *     Global_FO_RADIX('f')  - %f
2852    *     Global_FO_RADIX('F')  - %F
2853    *     Global_FO_RADIX('g')  - %g
2854    *     Global_FO_RADIX('G')  - %G
2855    *     Global_FO_RADIX('a')  - %a
2856    *     Global_FO_RADIX('A')  - %A
2857    */
2858  
2859  #define Global_FO_GET_RADIX(X)   (((X) >> Global_FO_RADIX_SHIFT) & Global_FO_RADIX_MASK)
2860  
2861  /* 6 bits -> +7 = 13 bits */
2862  #define Global_FO_NO_SEP         0UL   /* default: do not separate digits */
2863  #define Global_FO_SEP_AT_SHIFT   13UL
2864  #define Global_FO_SEP_AT_MASK    7UL
2865  #define Global_FO_SEP_AT(AT)     (((((unsigned long)(AT)) & Global_FO_SEP_AT_MASK) << Global_FO_SEP_AT_SHIFT) | Global_FO_DO_USE_SEP)
2866   /* Format option for Vector_oformat family: separate digits of numbers every AT digits.
2867    * If missing or 0, the a value of 3 is used.
2868    */
2869  
2870  #define Global_FO_GET_SEP_AT(X)  (((X) >> Global_FO_SEP_AT_SHIFT) & Global_FO_SEP_AT_MASK)
2871  
2872  /* 3 bits -> +13 = 16 bits */
2873  #define Global_FO_DO_USE_SEP     (1UL << 16)
2874   /* If set, digits are separated into digit groups.
2875    * Both FO_USE_SEP and FO_SET_AT macros automatically set this flag.
2876    */
2877  #define Global_FO_USE_SEP_SHIFT  17UL
2878  #define Global_FO_USE_SEP_MASK   255UL
2879  #define Global_FO_USE_SEP(C)     (((((unsigned long)((unsigned char)(C))) & Global_FO_USE_SEP_MASK) << Global_FO_USE_SEP_SHIFT) | Global_FO_DO_USE_SEP)
2880   /* Format option for Vector_oformat family:
2881    * The separator to use between digits if Global_FO_SEP_AT was specified.
2882    * The default separator is ','.
2883    */
2884  
2885  #define Global_FO_GET_USE_SEP(X) (((X) >> Global_FO_USE_SEP_SHIFT) & Global_FO_USE_SEP_MASK)
2886  
2887  /* 9 bits -> +16 = 25 bits */
2888  #define Global_FO_LOWCASE        0UL  /* default: digits are lowercase (except for %X) */
2889  #define Global_FO_UPCASE         (1UL << 25)
2890  /* Format option for Vector_oformat family: print digits in upper case.  This is most
2891   * useful together with the Global_FO_RADIX option.
2892   *
2893   * The default is to print in lower case.  Any mentioning of upper case in any
2894   * way will select upper case printing.  E.g. %X together with Global_FO_LOWCASE
2895   * will still print in upper case.  Similarly, %d together with Global_FO_LOWCASE
2896   * and Global_FO_RADIX('X') will print in upper case.
2897   */
2898  
2899  /* 1 bit -> +25 = 26 bits */
2900  #define Global_FO_PRINT          0UL  /* default: do print into vector. */
2901  #define Global_FO_CHECK          (1UL << 26)
2902  /* Format option for Vector_oformat family:  perform all formating actions without
2903   * modifying the Vector_t.  This is useful to compute the width of the resulting
2904   * string. */
2905  
2906  /* 1 bit -> +26 = 27 bits */
2907  #define Global_FO_SPECIAL        (1UL << 27)
2908  /* Same as # flag in format string: select special form.
2909   * The reason to give it is because %#d is not defined, but may be feasible
2910   * together with a RADIX() annotation, when you do want 0x and 0 prefixes.
2911   */
2912  
2913  /* 1 bit -> +27 = 28 bits
2914   *   There are five bits left.
2915   */
2916  #endif /* !defined(FO_C_STRING) */
2917  
2918  
2919  Global_ERWIN_EXPORT
2920  void Vector_set_quotation_method (
2921      Vector_t const * /* self */,
2922      int /* which */,
2923      Vector_quotation_method_t const *);
2924     /* Set new quotation methods for the `s' and `v' formats.
2925      * `which' may only be Global_FO_QUOTE_USER1 or Global_FO_QUOTE_USER2.
2926      *
2927      * self is needed to set the status code.
2928      *
2929      * This function is not thread safe, even if you define Global_ERWIN_THREAD_SAFE.
2930      * There is only one array of user quotation methods.  If you change it, do it
2931      * at the beginning of your program in the main thread!
2932      */
2933  
2934  Global_ERWIN_EXPORT
2935  Vector_quotation_method_t const *Vector_get_quotation_method (
2936      Vector_t const * /*self */,
2937      int /* which */);
2938     /* Get quotation methods.
2939      * Which must be from the Global_FO_QUOTE_* family.
2940      */
2941  
2942  Global_ERWIN_EXPORT
2943  void Vector_format (Vector_t * /*self*/, Tchar const * /*format*/, ...) ATTR_FORMAT_PRINTF(2, 3);
2944     /* See Vector_oformat. */
2945  
2946  Global_ERWIN_EXPORT
2947  void Vector_vformat (
2948      Vector_t * /*self*/,
2949      Tchar const * /*format*/,
2950      va_list) ATTR_FORMAT_VPRINTF(2);
2951     /* See Vector_oformat. */
2952  
2953  /* FIXME: have a scanf function, too, which especially does the unquoting
2954   * of all implemented formats. */
2955  
2956  Global_ERWIN_EXPORT
2957  void Vector_oformat (
2958      Vector_t * /*self*/,
2959      unsigned long /* options */,
2960      Tchar const * /*format*/, ...) ATTR_FORMAT_PRINTF(3, 4);
2961      /* The format is as in the printf family according to C99 standard. These functions will
2962       * never cause a buffer overflow. The \type(long long) type (64 bits integer) is supported
2963       * if the compiler supports one.  Its format  character is 'll', but `L' is also
2964       * understood.
2965       *
2966       * This function reimplements the whole
2967       * printf functionality, so if you do not like this overhead, you can define Vector_NO_FORMAT,
2968       * but because of the guaranteed prevention of buffer overflows, it is usually good
2969       * to use this.
2970       *
2971       * To keep ANSI/ISO conformance (ISO/IEC 9899:1999 = C99), all extra functionality has been
2972       * put into the additional `options' argument.  The following format options are supported:
2973       *
2974       *    +------------------------------+------------------------------------------------+
2975       *    | d, i, u, o, x, X, c, s, m, p | conversion, own implementation                 |
2976       *    | e, E, f, F, g, G, a, A       | conversions passed through to standard library |
2977       *    | #, 0, -, SPACE               | flags                                          |
2978       *    | h, hh, l, ll, L, j, z, t     | length                                         |
2979       *    +------------------------------+------------------------------------------------+
2980       *
2981       * Note: Use ll with integers only and L with floats only to be compliant with POSIX.
2982       *       (Erwin treats both exactly the same just like glibc.)
2983       *
2984       * Currently unsupported
2985       * ~~~~~~~~~~~~~~~~~~~~~
2986       *     +----+-------------------------------------+
2987       *     | $  | argument reordering                 |
2988       *     | n  | number of characters written so far |
2989       *     +----+-------------------------------------+
2990       *
2991       *     - L + float is only supported if the compiler has is a long double type
2992       *     - ll + int is only supported if the compiler has a 64 bit int type.
2993       *
2994       * Compatibility
2995       * ~~~~~~~~~~~~~
2996       * For compatibility, the following are implemented (don't use if you want to
2997       * be POSIX compliant).
2998       *     +----------------+--------------------------------------------------------+
2999       *     | C              | use lc instead                                         |
3000       *     | S              | use ls instead                                         |
3001       *     | Z              | use z  instead                                         |
3002       *     | q              | use ll instead                                         |
3003       *     | L + int        | use ll instead                                         |
3004       *     | ll + float     | use L instead                                          |
3005       *     | l + float      | double instead of float                                |
3006       *     | ' (apostrophy) | No locale support: always digit width 3, separator=' ' |
3007       *     +----------------+--------------------------------------------------------+
3008       *
3009       * Note: FO_RADIX(64) uses base-64 digits, but is not mmencode compatible, as the
3010       *       base64 encoding works on chunks of 3 bytes which are interpreted as
3011       *       4 6-bit digits each.  The problem is that the digit order is reversed to
3012       *       the normal order, so you cannot easily convert from the format output
3013       *       to real base64 output.  Maybe we'll introduce a quotation method for
3014       *       base64 some day.
3015       *
3016       * Further note that you can print negative number with base != 10 by using %d with
3017       * the option FO_RADIX(...).
3018       *
3019       * Options
3020       * ~~~~~~~
3021       * You can use the Global_FO_CHECK option to simulate operation.  By this, you can check
3022       * things via the first argument to Vector_rovformat or Vector_roformat.  The use
3023       * of Vector_format_pos() and Vector_format_quoted() is *deprecated*.
3024       *
3025       * The following options are supported to allow extended functionality.
3026       * They can be ORed together.
3027       *
3028       *     - Global_FO_VECTOR:
3029       *             All %p refer to a \type(Vector_t *) instead of to a \type(char *).
3030       *
3031       *     - Global_FO_UPCASE:
3032       *             Use upper case digits first in numbers (this is needed
3033       *             because there is no %D).
3034       *             e.g.
3035       *                 : format (Global_FO_UPCASE + Global_FO_RADIX(23), "%d", 2387)
3036       *             appends |4BI|
3037       *
3038       *     - Global_FO_CENTER:
3039       *             Selects centering.  I.e. in addition to default right
3040       *             adjustment or right adjustment by the |-| option.
3041       *
3042       *             This does not work for floating point
3043       *             arguments (see below) since the clib does not support it.
3044       *
3045       *             This can be combined with |-| to
3046       *             specify that if it cannot be centred exactly, it should
3047       *             be more left adjusted instead of right.
3048       *             E.g.
3049       *                : Vector_oformat (v, Global_FO_CENTER, "%04X", 10)
3050       *             will append "\tt(00A )" whereas
3051       *                : Vector_oformat (v, Global_FO_CENTER, "%-04X", 10)
3052       *             will append "\tt(0A  )".
3053       *
3054       *     - Global_FO_RADIX(radix):
3055       *             radix: a number between 0 and 64:
3056       *             Switches the radix of the %d, %i, %x and %o command from their
3057       *             default to this number.
3058       *
3059       *             The digit set is as follows:
3060       *
3061       *                 - radix <= 36:  for %x (lower case): 0..9, a..z and
3062       *                                 for %X (upper case): 0..9, A..Z
3063       *
3064       *                 - radix =  64:  always base64 digits (but different digit order!)
3065       *
3066       *                 - radix > 36 && radix < 64: base64 with only the first radix characters.
3067       *
3068       *             Also see the documentation of the Global_FO_RADIX macro to
3069       *             learn about the special radix values of 'd', 'i', 'o', 'x', 'X',
3070       *             'b', 'e', 'E', 'f', 'F', 'g', 'G', 'a', 'A'.
3071       *
3072       *     - Global_FO_QUOTE_SHELL:
3073       *             Quotation for Shell: either Unix or Windows, depending on compilation
3074       *             environment: equivalent to Global_FO_QUOTE_BOURNE_SHELL under Unix
3075       *             and te Global_FO_QUOTE_WIN_SHELL under Dos or Windows.
3076       *
3077       *     - Global_FO_QUOTE_BOURNE_SHELL:
3078       *             Quote for a Bourne shell.
3079       *                  : Vector_oformat (FO_QUOTE_BOURNE_SHELL, "%s", "a b!c")
3080       *             ->   \tt(a\ b\!c)
3081       *
3082       *     - Global_FO_QUOTE_WIN_SHELL:
3083       *             Quote for a Windows shell.
3084       *                  : Vector_oformat (FO_QUOTE_WIN_SHELL, "%s", "a b!c")
3085       *             ->   \tt("a b!c")
3086       *
3087       *     - Global_FO_QUOTE_C_STRING:
3088       *             Quote in double quoted C syntax.  Single quotes are still
3089       *             quoted as \'.  This also tries to get maximum compatibility
3090       *             for reading such a string by sometimes quoting although
3091       *             unnecessary since it is known that some buggy compilers may
3092       *             misinterpret something.  E.g. someone might read \0001 as
3093       *             only one character.  Therefore, the previous is quoted as
3094       *             \000\001.
3095       *
3096       *                  : Vector_oformat (FO_QUOTE_C_STRING, "%s", "a'b\\c\"d\0\7e")
3097       *             ->   \tt("a\'b\\c\"d\000\007e")
3098       *
3099       *             This handles NULL and prints it as NULL.
3100       *
3101       *     - Global_FO_QUOTE_IN_C_STRING:
3102       *             Similar to previous, but does not output enclosing double
3103       *             quotes, so it is suitable for either appending several
3104       *             quoted strings or for quoting in character syntax (single
3105       *             quotes), by manually providing enclosing quotes in the
3106       *             format string.
3107       *
3108       *                  : Vector_oformat (FO_QUOTE_C_STRING, "%s", "a'b\\c\"d\0\7e")
3109       *             ->   \tt(a\'b\\c\"d\000\007e)
3110       *
3111       *     - Global_FO_QUOTE_LISP_STRING:
3112       *             CommonLisp quotation: this is like a simple C quotation:
3113       *             basically, only " and \ need quotation.
3114       *
3115       *                  : Vector_oformat (FO_QUOTE_C_STRING, "%s", "a'b\\c\"d")
3116       *             ->   \tt("a'b\\c\"d")
3117       *
3118       *     - Global_FO_QUOTE_IN_LISP_STRING:
3119       *             Same as before without enclosing double quotes.
3120       *
3121       *                  : Vector_oformat (FO_QUOTE_C_STRING, "%s", "a'b\\c\"d")
3122       *             ->   \tt(a'b\\c\"d)
3123       *
3124       *     - Global_FO_QUOTE_FORMAT:
3125       *             Quote to be suitable as a printf format string.  I.e.,
3126       *             % is quoted as %%.  Note that this does not include a
3127       *             C quotation, so when you have a literal string, and want
3128       *             to print a format string in C, you'll need to first
3129       *             quote for format, and then again for C.
3130       *                  : Vector_oformat (FO_QUOTE_FORMAT, "%s", "%s")
3131       *             ->   \tt(%%s)
3132       *
3133       *     - Global_FO_QUOTE_USER1 ... USER3:
3134       *             User quotation: can be defined by the application by
3135       *             Vector_set_quotation_method().
3136       *
3137       *             Of the above, one can be selected: all %s and %c commands
3138       *             will quote their argument according to the given quotation.
3139       *
3140       *             Note: Quotation is only done for %s and %c, not for anything
3141       *                   else!
3142       *
3143       *             Further Note: because it appeared to happened *too*
3144       *             often, to mix quotation and non-quotation in one format string,
3145       *             you can specify left adjustment without giving a minimal width to
3146       *             switch off quotation.  So to switch off quotation for some %s,
3147       *             use %-s.
3148       *
3149       *             Note: This will only work if the minimal with is not given
3150       *             at all to prevent confusion:
3151       *
3152       *                  : Vector_oformat (FO_QUOTE_C_STRING, "%s.%-s.%s", "b", "c", "d")
3153       *             This will append:  \tt("b".c."d")
3154       *
3155       *     - Global_FO_SEP_AT(position):
3156       *             Position is a number between 0 and 15.
3157       *
3158       *             Put commas into a number.  E.g.
3159       *                 : oformat (Global_FO_SEP_AT(3), "%d", 10000000)
3160       *             ->  \tt(10,000,000)
3161       *
3162       *             This is equivalent to using "%'d" for an appropriate locale.
3163       *
3164       *             The number defines at how many digits this should happen.
3165       *             So Chinese people would perhaps want it between blocks of
3166       *             four digits:
3167       *
3168       *                 : oformat(Global_FO_SEP_AT(4), "%d", 10000000)
3169       *             ->  \tt(1000,0000)
3170       *
3171       *             (since 1000,0000 = qian1 wan4; qian1 (=1000) wan4 (=10000))
3172       *
3173       *             (For some unknown reason, however, it seems that Asian languages
3174       *             with base words up to 10000 (instead of 1000 as most Western European
3175       *             languages) still use separators at all three digits.  Why?)
3176       *
3177       *     - Global_FO_USE_SEP('.'):
3178       *             Define which character to use for digit separation:
3179       *
3180       *             E.g Germans might want to format their numbers like this:
3181       *                 : oformat(Global_FO_USE_SEP('.') |
3182       *                 :         Global_FO_SEP_AT(3), "%d", 10000000)
3183       *             ->  \tt(10.000.000)
3184       *
3185       *  Format specifiers
3186       *  ~~~~~~~~~~~~~~~~~
3187       *     - %n:  writes the current length of the vector into the given
3188       *             int* pointer. (or short* or long* or long long* if this
3189       *             is indicated by s, l or q).
3190       *
3191       *             Note: it writes the absolute length of the vector, NOT
3192       *             the relative length wrt. to the starting length!
3193       *
3194       *  Chopping behaviour with quoted strings
3195       *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3196       *
3197       *  When using both width arguments, characters will never be
3198       *  output in halves (or other pieces).  Instead, the string is
3199       *  tried to be kept shorter.  Sometimes this is not possible
3200       *  (e.g. when the length of the prefix + suffix exceeds the total
3201       *  width).  In rare cases the string will therefore be longer.
3202       *  This behaviour is useful for breaking strings over several lines.
3203       *
3204       *  If you specify the exact length argument, the string will still
3205       *  not be expanded or chopped. (e.g. %80.78s will produce
3206       *  lines which are always 80 characters wide and which contain
3207       *  at most 78 characters representing a string and which will
3208       *  be padded with spaces to the right):
3209       *  Example:
3210       *       : Vector_oformat(Global_FO_SHELL_QUOTE, "%7.5s", "Du da!")
3211       *       :   // This means: max. 5 chars, min.7 resulting in padding.)
3212       *  appends  \tt(Du\ d  )
3213       *
3214       *  The number of characters read from the input string can be
3215       *  retrieved by using Vector_roformat() or Vector_rovformat() and
3216       *  reading it from the resulting info structure.
3217       *
3218       *  E.g. the following loop generates a C parsable string which
3219       *  does not exceed 78 characters on each line:
3220       *      : int print_c_string (Vector_t *v, char const *c)
3221       *      : {
3222       *      :     Vector_format_info_t info;
3223       *      :     do {
3224       *      :         Vector_roformat (&info, Global_FO_QUOTE_C_STRING, v, "%.78s\n", c);
3225       *      :         c+= info.pos;
3226       *      :     } while (Global_VECTOR_IS_OK(Global_vector_errno) && *c != '\0');
3227       *      : }
3228       *
3229       * If more than one l, q, h and Z flag is given, the last one will be used.
3230       *
3231       * Note: float and double formatations are passed to the standard library.
3232       *       So whether e.g. long double is implemented depends on your clib.
3233       *       This includes the `a' and `A' conversions (GNU).
3234       *
3235       * Further Note:
3236       *       oType_ZERO will be used!  This means that if it is != '\0', the %s
3237       *       argument will terminate printing at the first character equal to
3238       *       oType_ZERO.
3239       */
3240  
3241  #IFNEQ (FORMAT_REPETITION,0)
3242      /*
3243       * Grouped Repetition:
3244       *     %NUM[ ... %]
3245       *             Repeat the sequence several times. E.g.:
3246       *                  Vector_format (v, "%3[%6d%]", i, o, p);
3247       *             It is allowed for NUM to be 0.  NUM defaults to 1.
3248       *
3249       *             It is also allowed for NUM to be `*' in which case the number
3250       *             is read from an integer argument.
3251       *
3252       *             If the special form character # is used, a pointer is read
3253       *             from the arg list used for all following arg list referencing.
3254       *             This pointer is also used for nested %[ forms.  If the nested
3255       *             are given with a special flag, the pointer from the nested
3256       *             form is read from the position of the outer special form
3257       *             pointer.  If NUM is * and the special form is given, the
3258       *             repetition number is still read without influence of the #.
3259       *
3260       *             Example 1: You can print the argument list of a program with
3261       *               Vector_format (v, "%#*[%< %.2s%]", argc, argv);
3262       *
3263       *             Example 2: You can output a two dimensional 3x3 array like this:
3264       *               Vector_format (v, "%#3[%3[%6d,%]\n%]", a);
3265       *
3266       *             Note: For floating pointer arguments, you must use `lf' for a
3267       *                   double like in fscanf when reading from pointers.
3268       *
3269       *      %NUM<
3270       *      %NUM>  Skip the following NUM characters of the format string if this
3271       *             is the first (last) iteration of the innermost repetition loop.
3272       *             NUM defaults to 1.
3273       *             The special form reverses the logic.
3274       *
3275       *             Example:  You can output the above array in C syntax is follows:
3276       *               Vector_format (v, "int a[3][3]={%#3[{ %3[ %6d%>,%] }%2>,\n%]};\n", a);
3277       *
3278       */
3279  #ENDIF /* FORMAT_REPETITION */
3280  
3281  Global_ERWIN_EXPORT
3282  void Vector_ovformat (
3283      Vector_t *    /* self */,
3284      unsigned long /* options */,
3285      Tchar const *  /* format */,
3286      va_list       /* arguments */) ATTR_FORMAT_VPRINTF(3);
3287     /* See Vector_oformat. */
3288  
3289  Global_ERWIN_EXPORT
3290  void Vector_format_info_init (Vector_format_info_t *);
3291     /* Initialises a Vector_format_info_t structure.  Only required for C code.
3292      * In C++, the constructor is used for this.
3293      *
3294      * A Vector_format_info_t structure must be initialised before invoking
3295      * Vector_rovformat() with a pointer to it.
3296      */
3297  
3298  Global_ERWIN_EXPORT
3299  void Vector_format_info_done (Vector_format_info_t *);
3300     /* Sweeps a Vector_format_info_t structure.  Only required for C code.
3301      * In C++, the destructor is used for this.
3302      *
3303      * A Vector_format_info_t structure must be sweeps before deallocation.
3304      */
3305  
3306  Global_ERWIN_EXPORT
3307  void Vector_roformat (
3308      Vector_format_info_t * /* info */,
3309      Vector_t * /* self */,
3310      unsigned long /* options */,
3311      Tchar const * /* format */,
3312      ... /* arguments */) ATTR_FORMAT_PRINTF(4, 5);
3313     /* Additional to Vector_oformat it stores information about the performed formatting
3314      * in info.  Use this in favour of Vector_format_quoted to retrieve information you
3315      * need.
3316      */
3317  
3318  Global_ERWIN_EXPORT
3319  void Vector_rovformat (
3320      Vector_format_info_t * /* info */,
3321      Vector_t *   /* self */,
3322      unsigned long /* options */,
3323      Tchar const *   /* format */,
3324      va_list       /* arguments */) ATTR_FORMAT_VPRINTF(4);
3325     /* Additional to Vector_ovformat it stores information about the performed formatting
3326      * in info.  Use this in favour of Vector_format_quoted to retrieve information you
3327      * need.
3328      */
3329  
3330  #if Global_ERWIN_GLOBAL_ERRNO
3331  Global_ERWIN_EXPORT
3332  Global_ERWIN_BOOL Vector_format_quoted (void) ATTR_DEPRECATED;
3333      /* DEPRECATED
3334       * ----------
3335       * Use
3336       *     : Vector_roformat (&info, FO_CHECK ...
3337       *
3338       * Was quotation ever necessary during the format?
3339       *
3340       * This function is not thread safe.  It uses global variables.  Therefore, this
3341       * function is not available when you compile with thread support
3342       * (Global_ERWIN_THREAD_SAFE).  Use Vector_rovformat or Vector_roformat.
3343       */
3344  
3345  Global_ERWIN_EXPORT
3346  Vector_index_t  Vector_format_pos (void) ATTR_DEPRECATED;
3347      /* DEPRECATED
3348       * ----------
3349       * Use
3350       *     : Vector_roformat (&info, FO_CHECK ...
3351       *
3352       * Returns how many characters were read from the last %s command.
3353       *
3354       * This function is not thread safe.  It uses global variables.  Therefore, this
3355       * function is not available when you compile with thread support
3356       * (Global_ERWIN_THREAD_SAFE).  Use Vector_rovformat or Vector_roformat.
3357       */
3358  
3359  #endif /* Global_ERWIN_GLOBAL_ERRNO */
3360  
3361  #endif /* Vector_NO_FORMAT==0 */
3362  
3363  #ENDIF
3364  
3365  /*--END-C--*/
3366  
3367  #include "#Vector_i.ErwinHExt"
3368  /* Same problem as for arrays.  For efficient implementation, the compiler
3369   * needs to know the size of a vector structure.
3370   */
3371  
3372  #IFCPPONLY
3373  #ELSE
3374  #if defined(__cplusplus)
3375  }
3376  #endif /* __cplusplus */
3377  #ENDIF
3378  
3379  /*
3380   * If initial_size < 0 for any of the following functions, the default
3381   * size will be used.
3382   */
3383  
3384  struct Vector_t
3385  #ifdef Vector_SUPER_CLASS
3386     : Vector_SUPER_CLASS_ACCESS Vector_SUPER_CLASS
3387  #endif
3388  {
3389      /*
3390       * The Vector Class
3391       * ================
3392       * This class implements dynamically resizable arrays.
3393       *
3394       * Throughout the documentation, the following prefixes will be used:
3395       *   - Global_:
3396       *       The library prefix: for applications, this is typically
3397       *       empty, for an xyz-Library, this is either \tt(XYZ_), \tt(xyz_) or
3398       *       \tt(Xyz), depending on the identifier in occurs in.
3399       *       +---------------------+-----------------+
3400       *       |! Template           |! Instantiation  |
3401       *       | Global_VECTOR_OK    | XYZ_VECTOR_OK   |
3402       *       | Global_vector_new   | xyz_vector_new  |
3403       *       +---------------------+-----------------+
3404       *
3405       *   - Vector_:
3406       *       This is equivalent to Global_vector_oType, or the name
3407       *       that was set with \tt(-name=...) for this data structure.
3408       *       The case and underbar convention is adjusted, too.
3409       *
3410       *       Assuming a library prefix \tt(xyz) and oType == char, you get:
3411       *       +-------------------+----------------------------+
3412       *       |! Template         |! Instantiation             |
3413       *       | Vector_t          | xyz_vector_char_t          |
3414       *       | Vector_ALLOW_NULL | XYZ_VECTOR_CHAR_ALLOW_NULL |
3415       *       +-------------------+----------------------------+
3416       *   - Vector_class:
3417       *       This is the name of the data structure type in C++: capitalised
3418       *       and with underbars removed:
3419       *       +-------------------+-----------------+
3420       *       |! Vector_t         |! Vector_class   |
3421       *       | vector_char_t     | VectorChar      |
3422       *       +-------------------+-----------------+
3423       *
3424       * Conventions
3425       * -----------
3426       *
3427       * It was tried to keep the argument order consistent, with some rules:
3428       *
3429       *    - for functions returning multiple values into pointer arguments, these
3430       *      are always /before/ input arguments. (e.g. Vector_locate (output, self, ...)).
3431       *      (Mnemonic: like memcpy, strcpy, assignment statement etc.)
3432       *       : Global_ERWIN_BOOL Vector_locate (int *i, Vector_t const *, ...)
3433       *       : ^output                          ^output ^input            ^input
3434       *       :                                          ^first input = self
3435       *    - the self argument is always the first input argument.
3436       *    - index before element   (e.g.,
3437       *       : Vector_insert (self, position, element)
3438       *    - count after element(s). E.g.:
3439       *       : Vector_insert_raw (self, position, elemnt_ptr, count)
3440       *    - flags last. E.g.:
3441       *       : Vector_overwrite_flags (self, start, value, count,
3442       *       :                         copy_elems, delete_overwritten)
3443       *
3444       * Results
3445       * ~~~~~~~
3446       *   - if there is no natural result value, C functions return their success,
3447       *     i.e., the value of Global_vector_errno:
3448       *       : int Vector_erase (Vector_t *self, int pos, int count)
3449       *     In these circumstances, C++ functions return the vector itself as
3450       *     a reference:
3451       *       : Vector_t &Vector_t::erase (int pos, int count = 1)
3452       *   - if Vector_errno is not interesting, either because it is not
3453       *     set or because only memory overflow or assertion failures may be
3454       *     a possible sources of an error, the C functions return void:
3455       *       : void Vector_delete (Vector_t *self)
3456       *     The C++ functions still return the object reference.
3457       *
3458       * Status Codes
3459       * ------------
3460       *
3461       * These are undef'ed first because there is only one error code for all
3462       * the arrays in your program.
3463       * All the functions returing error codes will both return this error
3464       * and write it into Global_vector_errno.
3465       *
3466       *    +-----------------------+---------------------------+-----------------------------+
3467       *    |! Condition            |! Description              |! Macro to use               |
3468       *    +-----------------------+---------------------------+-----------------------------+
3469       *    | == Global_VECTOR_OK   | Ok.                       | Global_VECTOR_IS_OK(X)      |
3470       *    +-----------------------+---------------------------+-----------------------------+
3471       *    | <  Global_VECTOR_OK   | *Error*: operation did    | Global_VECTOR_IS_ERROR(X)   |
3472       *    |                       | not succeed.              |                             |
3473       *    +-----------------------+---------------------------+-----------------------------+
3474       *    | >  Global_VECTOR_OK   | *Warning*: operation      | Global_VECTOR_IS_WARNING(X) |
3475       *    |                       | succeeded but not         |                             |
3476       *    |                       | perfectly. (e.g. rehash   |                             |
3477       *    |                       | failed)                   |                             |
3478       *    +-----------------------+---------------------------+-----------------------------+
3479       *
3480       *
3481       *  In all cases, the consistency of the data structure is guaranteed.
3482       *
3483       *  Warnings are only visible in Global_vector_errno; the functions still return
3484       *  VECTOR_OK.
3485       */
3486  
3487      Vector_STD_MEMBERS(Vector_t)
3488  
3489  #ifdef __cplusplus
3490  public: /* The implementation is in C, so these need access. */
3491  #endif /* defined __cplusplus */
3492  
3493      Vector_record
3494  
3495  #ifdef __cplusplus
3496  
3497      /*! doc-ignore */
3498      Vector_t *it()             { return this; }
3499  
3500      /*! doc-ignore */
3501      Vector_t const *it() const { return this; }
3502  
3503  /*--BEGIN-CLASS--*/
3504  public:
3505  #ifdef __cplusplus
3506  #if !Global_ERWIN_DEFAULT_NEW_DELETE
3507      static void *operator new(size_t);
3508      static void operator delete(void *, size_t);
3509      static void *operator new[](size_t);
3510      static void operator delete[](void *, size_t);
3511  #endif
3512  #endif
3513  
3514      /* Creation */
3515  
3516      Vector_t (void);
3517  
3518      static Vector_t const &static_zero();
3519  
3520  #if Vector_HAVE_INT_CONSTRUCTOR
3521      Global_ERWIN_EXPLICIT Vector_t (Vector_cnt_t initial_size);
3522  #endif
3523  #if Vector_DYN_ZERO
3524      Global_ERWIN_EXPLICIT Vector_t (oTypeTouched);
3525      Vector_t (oTypeTouched, Vector_cnt_t);
3526  #endif
3527  
3528      /*
3529       * Enforced vector copying.  All of the following functions create a new vector
3530       * and leave the old one (if any) intact.  It can be defined whether the elements
3531       * are to be copied. */
3532  
3533      Vector_t (Vector_t const *, bool do_copy Vector_DEFAULT_ARG(true));
3534  
3535      Vector_t (Vector_t const *, Vector_index_t, Vector_cnt_t, bool do_copy Vector_DEFAULT_ARG(true));
3536  
3537      Vector_t (oTypeVar const *, bool do_copy Vector_DEFAULT_ARG(true));
3538      Vector_t (oTypeVar const *, Vector_cnt_t, bool do_copy Vector_DEFAULT_ARG(true));
3539  #IFEQ(oType,oTypeVar)
3540  #ELSE
3541      Global_ERWIN_EXPLICIT Vector_t (oType const *);
3542      Vector_t (oType const *, Vector_cnt_t);
3543  #ENDIF
3544  
3545      /* The following is thought to be for coercing arrays to vectors.  The vector
3546       * then operates directly on the given array.  See Vector_new_from_raw for
3547       * details. */
3548  
3549      Vector_t (bool       /* must_be_true */,
3550                oTypeVar * /* other */,
3551                Vector_cnt_t        /* count */,
3552                Vector_cnt_t        /* alloc */);
3553         /* alloc may be -1: see Vector_new_from_raw */
3554  
3555  #if Vector_DYN_ZERO
3556      Vector_t (bool         /* must_be_true */,
3557                oTypeVar *   /* other */,
3558                Vector_cnt_t          /* count */,
3559                Vector_cnt_t          /* alloc */,
3560                oTypeTouched /* zero_element */);
3561         /* alloc may be -1: see Vector_new_from_raw */
3562  #endif
3563  
3564      Vector_t (bool       /* must_be_true */,
3565                Vector_t * /* other */);
3566  
3567      Vector_t (bool       /* must_be_true */,
3568                Vector_t & /* other */);
3569  
3570      void _constructor (void);
3571      void _destructor  (void);
3572  
3573      /* Check for NULL pointers */
3574  protected:
3575  #ifndef NDEBUG
3576      void cn() const;
3577      void cn(void const *) const;
3578  #else
3579      /* Hopefully optimised away: */
3580      static void cn() {}
3581      static void cn(void const *) {}
3582  #endif
3583  
3584  public:
3585      /* Status code */
3586  
3587  #if !Global_ERWIN_GLOBAL_ERRNO
3588      int get_errno(void) const
3589      { return it()->m_errno; }
3590  
3591      void clear_errno(void) const
3592      { Vector_clear_errno (it()); }
3593  #else
3594      static int get_errno(void)
3595      { return Global_vector_errno; }
3596  
3597      static void clear_errno(void)
3598      { Global_vector_errno= Global_VECTOR_OK; }
3599  #endif
3600  
3601      /* Copying */
3602  
3603      Vector_t (Vector_t const &, bool docopy Vector_DEFAULT_ARG(true));
3604      Vector_t (Vector_t const &, Vector_index_t, Vector_cnt_t, bool do_copy Vector_DEFAULT_ARG(true));
3605  
3606      Vector_t *copy (void) const
3607      {
3608          if (this == NULL)
3609              return NULL;
3610          return new Vector_t (it(), true);
3611      }
3612  
3613      Vector_t *copy_err (int *err) const
3614      {
3615          if (this == NULL) /* special case for copy function */
3616              return NULL;
3617          Vector_t *result= new Vector_t (it(), true);
3618          if (err != NULL && Global_VECTOR_IS_ERROR (get_errno()))
3619              *err= 1;
3620          return result;
3621      }
3622  
3623      /* The following functions assume that Vector_t and Vector_t are the
3624       * same type making things more easy.  Since they did not exist in pre 2.0.265,
3625       * we can simply not declare them when the compat is define. */
3626  
3627      Vector_t *copy_detach()
3628      {
3629          return Vector_new_from_vector (it());
3630      }
3631  
3632      Vector_t &xchg(Vector_t *other)
3633      {
3634          Vector_xchg (it(), other);
3635          return *this;
3636      }
3637  
3638      Vector_t &xchg(Vector_t &other)
3639      {
3640          Vector_xchg (this, &other);
3641          return *this;
3642      }
3643  
3644      /* Normal members */
3645  
3646      Vector_t *subvector (Vector_index_t b, Vector_cnt_t c) const
3647      {
3648          return new Vector_t (this, b, c, true);
3649      }
3650  
3651      Vector_t *subvector (Vector_index_t b, Vector_cnt_t c, bool d) const
3652      {
3653          return new Vector_t (this, b, c, d);
3654      }
3655  
3656  
3657      /* Assignment */
3658  
3659      Vector_t &operator=(Vector_t const &);
3660      Vector_t &operator=(Vector_t const *);
3661  
3662      /* Destruction */
3663  
3664      ~Vector_t ();
3665  
3666      /* Re-init by dropping responsibility for the table: */
3667  
3668      Vector_t &detach (void)
3669      { Vector_detach (it()); return *this; }
3670  
3671      Vector_t &detach_as_is (void)
3672      { Vector_detach_as_is (it()); return *this; }
3673  
3674      /* Conversion to C type <= 2.0.264 / conversion to pointer > 2.0.264 */
3675  
3676      operator Vector_t const *() const
3677      { return it(); }
3678  
3679      operator Vector_t *()
3680      { return it(); }
3681  
3682      /* operator int () const { cn(); return get_errno(); }
3683       * FIXME: maybe add this one day.  It produces invisible semantics changes with
3684       * old versions when 'explicit' is used as well. */
3685  
3686  #if Vector_MANY_CASTS != 0
3687      operator Vector_element_ptr_t () const
3688      { return as_array(); }
3689  
3690      operator bool () const
3691      { return !empty(); }
3692  #endif
3693  
3694  #if Vector_POSITION_POINTER
3695      Vector_index_t *pos_ptr ()                 { return &m_pos; }
3696      Vector_index_t &pos_ref ()                 { return m_pos;  }
3697      Vector_index_t  pos     ()                 { return m_pos;  }
3698      void            set_pos (Vector_index_t y) { m_pos= y;      }
3699  #endif
3700  
3701      oTypeResult nth (Vector_index_t i) const
3702      {
3703  #ifdef Vector_INLINE__NTH
3704          cn();
3705          return m_table[i];
3706  #else
3707          return Vector_nth (it(), i);
3708  #endif
3709      }
3710  
3711      oTypeResult nth_char (Vector_index_t i) const
3712      { return Vector_nth_char (it(), i); }
3713  
3714      Vector_element_ptr_t nth_ptr_check (Vector_index_t i)
3715      {
3716          return Vector_nth_ptr_check (it(), i);
3717      }
3718  
3719      oType const *nth_ptr_check (Vector_index_t i) const
3720      {
3721          return Vector_nth_ptr_check_const (it(), i);
3722      }
3723  
3724      Vector_element_ptr_t nth_ptr_char (Vector_index_t i)
3725      {
3726          return Vector_nth_ptr_char (it(), i);
3727      }
3728  
3729      oType const *nth_ptr_char (Vector_index_t i) const
3730      {
3731          return Vector_nth_ptr_char_const (it(), i);
3732      }
3733  
3734      Vector_element_ptr_t nth_ptr (Vector_index_t i)
3735      {
3736          return Vector_nth_ptr (it(), i);
3737      }
3738  
3739      oType const *nth_ptr (Vector_index_t i) const
3740      {
3741          return Vector_nth_ptr_const (it(), i);
3742      }
3743  
3744      Vector_element_ref_t nth_ref (Vector_index_t i)
3745      {
3746          return *(Vector_nth_ptr (it(), i));
3747      }
3748  
3749      oType const &nth_ref (Vector_index_t i) const
3750      {
3751          return *(Vector_nth_ptr_const (it(), i));
3752      }
3753  
3754      Vector_element_ref_t nth_ref_check (Vector_index_t i)
3755      {
3756          return *(Vector_nth_ptr_check (it(), i));
3757      }
3758  
3759      oType const &nth_ref_check (Vector_index_t i) const
3760      {
3761          return *(Vector_nth_ptr_check_const (it(), i));
3762      }
3763  
3764      Vector_element_ref_t nth_ref_char (Vector_index_t i)
3765      {
3766          return *(Vector_nth_ptr_char (it(), i));
3767      }
3768  
3769      oType const &nth_ref_char (Vector_index_t i) const
3770      {
3771          return *(Vector_nth_ptr_char_const (it(), i));
3772      }
3773  
3774  
3775  #IFEQ (isChar,1)
3776  
3777      oTypeResult operator[] (Vector_index_t i) const
3778      { return nth_char (i); }
3779  
3780      Vector_element_ref_t operator[] (Vector_index_t i)
3781      { return *nth_ptr_char (i); }
3782  
3783  #ELSE
3784  
3785      Vector_element_ref_t operator[] (Vector_index_t i)
3786      { return *nth_ptr_check (i); }
3787  
3788      oTypeResult operator[] (Vector_index_t i) const
3789      { return nth (i); }
3790  
3791  #ENDIF
3792  
3793      oTypeResult first (void) const
3794      {
3795          return nth (0);
3796      }
3797  
3798      Vector_element_ptr_t first_ptr ()
3799      {
3800          return Vector_first_ptr (it());
3801      }
3802  
3803      Vector_element_ref_t first_ref ()
3804      {
3805          return *(Vector_first_ptr (it()));
3806      }
3807  
3808      oTypeResult last (void) const
3809      {
3810          return nth (nentries()-1);
3811      }
3812  
3813      Vector_element_ptr_t last_ptr ()
3814      {
3815          return Vector_last_ptr (it());
3816      }
3817  
3818      Vector_element_ref_t last_ref ()
3819      {
3820          return *(Vector_last_ptr (it()));
3821      }
3822  
3823      oTypeVar modify (Vector_index_t i, oTypeTouched v)
3824      { return Vector_modify (it(), i, v); }
3825  
3826      Vector_t &reverse (void)
3827      {
3828          Vector_reverse (it());
3829          return *this;
3830      }
3831  
3832      oTypeVar last_chop1 (void)
3833      {
3834          return Vector_last_chop1 (it());
3835      }
3836  
3837      oTypeVar first_swap_chop1 (void)
3838      {
3839          return Vector_first_swap_chop1 (it());
3840      }
3841  
3842      /* Set */
3843  
3844      Vector_t &set (Vector_index_t i, oTypeTouched v)
3845      { Vector_set (it(), i, v); return *this; }
3846  
3847      /* Erase family */
3848  
3849      Vector_t &swap_erase (Vector_index_t i, Vector_cnt_t n = -1)
3850      { Vector_swap_erase (it(), i, n); return *this; }
3851  
3852  
3853  #IFEQ(oType,oTypeVar)
3854      Vector_t &swap_erase (Vector_index_t i, Vector_cnt_t n, bool a, bool b=true)
3855      {
3856          Vector_swap_erase_flags (it(), i, n, a, b);
3857          return *this;
3858      }
3859  #ENDIF
3860  
3861      Vector_t &erase (Vector_index_t i, Vector_cnt_t n = -1)
3862      { Vector_erase (it(), i, n); return *this; }
3863  
3864  
3865      Vector_cnt_t erase_zero ()
3866      {
3867          return Vector_erase_zero (it());
3868      }
3869  
3870  #IFEQ(oType,oTypeVar)
3871      Vector_t &erase (Vector_index_t i, Vector_cnt_t n, bool a, bool b=true)
3872      {
3873          Vector_erase_flags (it(), i, n, a, b);
3874          return *this;
3875      }
3876  
3877      Vector_cnt_t erase_if (Vector_feature_t f,
3878                    bool inv Vector_DEFAULT_ARG(true),
3879                    bool a   Vector_DEFAULT_ARG(true),
3880                    bool b   Vector_DEFAULT_ARG(true))
3881      {
3882          return Vector_erase_if_flags (it(), f, inv,a,b);
3883      }
3884  
3885      Vector_cnt_t erase_if_not (
3886                    Vector_feature_t f,
3887                    bool inv Vector_DEFAULT_ARG(true),
3888                    bool a   Vector_DEFAULT_ARG(true),
3889                    bool b   Vector_DEFAULT_ARG(true))
3890      {
3891          return Vector_erase_if_flags (it(), f, !inv, a, b);
3892      }
3893  
3894      Vector_cnt_t erase_equals (Vector_cmp_t fcmp Vector_DEFAULT_ARG(Vector_CMP_T_NULL),
3895                        Vector_combine_t combine Vector_DEFAULT_ARG(Vector_COMBINE_T_NULL))
3896      {
3897          return Vector_erase_equals (it(), fcmp, combine);
3898      }
3899  
3900  #ELSE
3901      Vector_t &erase (Vector_index_t i, Vector_cnt_t n, bool a)
3902      {
3903          Vector_erase_flags (it(), i, n, a);
3904          return *this;
3905      }
3906  
3907      Vector_cnt_t erase_if (Vector_feature_t f,
3908                    bool inv Vector_DEFAULT_ARG(true),
3909                    bool a   Vector_DEFAULT_ARG(true))
3910      {
3911          return Vector_erase_if_flags (it(), f, inv, a);
3912      }
3913  
3914      Vector_cnt_t erase_if_not (
3915                    Vector_feature_t f,
3916                    bool inv Vector_DEFAULT_ARG(true),
3917                    bool a   Vector_DEFAULT_ARG(true))
3918      {
3919          return Vector_erase_if_flags (it(), f, !inv, a);
3920      }
3921  
3922  #ENDIF
3923  
3924      Vector_t &swap_chop (Vector_cnt_t n Vector_DEFAULT_ARG(1))
3925      {
3926          Vector_swap_erase (it(), 0, n);
3927          return *this;
3928      }
3929  
3930  #IFEQ(oType,oTypeVar)
3931      Vector_t &swap_chop (bool a, bool b Vector_DEFAULT_ARG(true))
3932      {
3933          Vector_swap_erase_flags (it(), 0, 1, a, b);
3934          return *this;
3935      }
3936      Vector_t &swap_chop (Vector_cnt_t n, bool a, bool b Vector_DEFAULT_ARG(true))
3937      {
3938          Vector_swap_erase_flags (it(), 0, n, a, b);
3939          return *this;
3940      }
3941  #ELSE
3942  #if 0
3943      /* bool against int is a bad overloading technique, since it introduces
3944       * very bad ambiguities */
3945  
3946      Vector_t &swap_chop (bool a)
3947      {
3948          Vector_swap_erase_flags (it(), 0, 1, a);
3949          return *this;
3950      }
3951  #endif
3952  
3953      Vector_t &swap_chop (Vector_cnt_t n, bool a)
3954      {
3955          Vector_swap_erase_flags (it(), 0, n, a);
3956          return *this;
3957      }
3958  #ENDIF
3959  
3960      Vector_t &chop (Vector_cnt_t n Vector_DEFAULT_ARG(1))
3961      {
3962          Vector_chop (it(), n);
3963          return *this;
3964      }
3965  
3966  #IFEQ(oType,oTypeVar)
3967      Vector_t &chop (bool a, bool b Vector_DEFAULT_ARG(true))
3968      {
3969          Vector_chop_flags (it(), 1, a, b);
3970          return *this;
3971      }
3972      Vector_t &chop (Vector_cnt_t n, bool a, bool b Vector_DEFAULT_ARG(true))
3973      {
3974          Vector_chop_flags (it(), n, a, b);
3975          return *this;
3976      }
3977  #ELSE
3978  #if 0
3979      /* bool against int is a bad overloading technique, since it introduces
3980       * very bad ambiguities */
3981  
3982      Vector_t &chop (bool a)
3983      {
3984          Vector_chop_flags (it(), 1, a);
3985          return *this;
3986      }
3987  #endif
3988      Vector_t &chop (Vector_cnt_t n, bool a)
3989      {
3990          Vector_chop_flags (it(), n, a);
3991          return *this;
3992      }
3993  #ENDIF
3994  
3995      Vector_t &prepend (oTypeTouched a)
3996      { Vector_insert (it(), 0, a); return *this; }
3997  
3998      Vector_t &prepend_raw     (oType const *a, Vector_cnt_t n)
3999      { Vector_insert_raw (it(), 0, a, n); return *this; }
4000  
4001      Vector_t &prepend_no_copy (oTypeVar const *a, Vector_cnt_t n)
4002      { Vector_insert_no_copy (it(), 0, a, n); return *this; }
4003  
4004      Vector_t &prepend_vector  (Vector_t const *a)
4005      { Vector_insert_vector (it(), 0, a->it()); return *this; }
4006  
4007      Vector_t &prepend_vector  (Vector_t const &a)
4008      { Vector_insert_vector (it(), 0, a.it()); return *this; }
4009  
4010      Vector_t &prepend_string  (oType const *a)
4011      { Vector_insert_string (it(), 0, a); return *this; }
4012  
4013  
4014      Vector_t &append (oTypeTouched a)
4015      { Vector_append (it(), a); return *this; }
4016  
4017      Vector_t &append_raw     (oType const *a, Vector_cnt_t n)
4018      { Vector_append_raw (it(), a, n); return *this; }
4019  
4020      Vector_t &append_no_copy (oTypeVar const *a, Vector_cnt_t n)
4021      { Vector_append_no_copy (it(), a, n); return *this; }
4022  
4023      Vector_t &append_vector  (Vector_t const *a)
4024      { Vector_append_vector (it(), a->it()); return *this; }
4025  
4026      Vector_t &append_vector  (Vector_t const &a)
4027      { Vector_append_vector (it(), a.it()); return *this; }
4028  
4029      Vector_t &append_string  (oType const *a)
4030      { Vector_append_string (it(), a); return *this; }
4031  
4032      Vector_t &append_subvector (
4033          Vector_t const &a,
4034          Vector_index_t b,
4035          Vector_cnt_t c Vector_DEFAULT_ARG (-1),
4036          Global_ERWIN_BOOL d Vector_DEFAULT_ARG (Global_ERWIN_TRUE))
4037      {
4038          return insert_subvector (0, a, b, c, d);
4039      }
4040  
4041      Vector_t &append_subvector (
4042          Vector_t const *a,
4043          Vector_index_t b,
4044          Vector_cnt_t c Vector_DEFAULT_ARG (-1),
4045          Global_ERWIN_BOOL d Vector_DEFAULT_ARG (Global_ERWIN_TRUE))
4046      {
4047          return insert_subvector (0, a, b, c, d);
4048      }
4049  
4050  #if Vector_DIRECT_RECURSION == 0
4051      /* The following function is really bad when format() is defined and you mix up
4052         append and format.
4053  
4054         Compare:
4055              : v->append ("There are many pieces");
4056              : v->format ("There are many pieces");
4057  
4058         These are equivalent.  I would choose to use append here.  But look at this:
4059              : v->append ("There are %d pieces", i);
4060              : v->format ("There are %d pieces", i);
4061  
4062         Of course, the second one was meant here.  This is an easy typo the compiler
4063         cannot warn about.
4064  
4065         Therefore, Erwin does not implement the following function.  It is still
4066         available via append_raw.
4067      */
4068  
4069      /*
4070      int append (oType const *a, int n)
4071      { return Vector_append_raw (it(), a, n); }
4072      */
4073  
4074      Vector_t &prepend (Vector_t const *a)
4075      { Vector_insert_vector (it(), 0, a->it()); return *this; }
4076  
4077      Vector_t &prepend (Vector_t const &a)
4078      { Vector_insert_vector (it(), 0, a.it()); return *this; }
4079  
4080      Vector_t &prepend (oType const *a)
4081      { Vector_insert_string (it(), 0, a); return *this; }
4082  
4083      Vector_t &append (Vector_t const *a)
4084      { Vector_append_vector (it(), a->it()); return *this; }
4085  
4086      Vector_t &append (Vector_t const &a)
4087      { Vector_append_vector (it(), a.it()); return *this; }
4088  
4089      Vector_t &append (oType const *a)
4090      { Vector_append_string (it(), a); return *this; }
4091  
4092      Vector_t &operator<< (oType const *a)
4093      { Vector_append_string (it(), a); return *this; }
4094  
4095     /* For the same reason as the one above, we will not implement the following functions, since
4096      * the second one may be invoked for append ("Test", 4) with an autocast.  You will then
4097      * effectively append "", which is probably not what you want.  The first one is
4098      * not implemented for symmetry reasons.
4099  
4100      Vector_t &append (
4101          Vector_t const *a,
4102          Vector_index_t b,
4103          Vector_index_t c Vector_DEFAULT_ARG (-1),
4104          Global_ERWIN_BOOL d Vector_DEFAULT_ARG (Global_ERWIN_TRUE))
4105      {
4106          return append_subvector (a, b, c, d);
4107      }
4108  
4109      Vector_t &append (
4110          Vector_t const &a,
4111          Vector_index_t b,
4112          Vector_index_t c Vector_DEFAULT_ARG (-1),
4113          Global_ERWIN_BOOL d Vector_DEFAULT_ARG (Global_ERWIN_TRUE))
4114      {
4115          return append_subvector (a, b, c, d);
4116      }
4117      */
4118  
4119  #endif /* Vector_DIRECT_RECURSION == 0*/
4120  
4121      Vector_t &operator<< (oTypeTouched a)
4122      { Vector_append (it(), a); return *this; }
4123  
4124      Vector_t &operator<< (Vector_t const*a)
4125      { Vector_append_vector (it(), a->it()); return *this; }
4126  
4127      Vector_t &operator<< (Vector_t const&a)
4128      { Vector_append_vector (it(), a.it()); return *this; }
4129  
4130      /* Find family */
4131  
4132      Vector_index_t find (oTypeParam needle) const
4133      { return Vector_find (it(), 0, needle); }
4134  
4135      Vector_index_t find_raw (oType const *needle, Vector_cnt_t n) const
4136      { return Vector_find_raw (it(), 0, needle, n); }
4137  
4138      Vector_index_t find_string (oType const *needle) const
4139      { return Vector_find_raw (it(), 0, needle, string_length (needle)); }
4140  
4141      Vector_index_t find_vector (Vector_t const &needle) const
4142      { return Vector_find_raw (it(), 0, needle.it()->m_table, needle.it()->m_nentries); }
4143  
4144      Vector_index_t find_vector (Vector_t const *needle) const
4145      { return Vector_find_raw (it(), 0, needle->it()->m_table, needle->it()->m_nentries); }
4146  
4147  #if Vector_DIRECT_RECURSION == 0
4148      Vector_index_t find (oType const *needle, Vector_cnt_t n) const
4149      { return Vector_find_raw (it(), 0, needle, n); }
4150  
4151      Vector_index_t find (oType const *needle) const
4152      { return Vector_find_raw (it(), 0, needle, string_length (needle)); }
4153  
4154      Vector_index_t find (Vector_t const &needle) const
4155      { return Vector_find_raw (it(), 0, needle.it()->m_table, needle.it()->m_nentries); }
4156  
4157      Vector_index_t find (Vector_t const *needle) const
4158      { return Vector_find_raw (it(), 0, needle->it()->m_table, needle->it()->m_nentries); }
4159  #endif
4160  
4161      Vector_index_t find (Vector_index_t a, oTypeParam needle) const
4162      { return Vector_find (it(), a, needle); }
4163  
4164      Vector_index_t find_raw (Vector_index_t a, oType const *needle, Vector_cnt_t n) const
4165      { return Vector_find_raw (it(), a, needle, n); }
4166  
4167      Vector_index_t find_string (Vector_index_t a, oType const *needle) const
4168      { return Vector_find_raw (it(), a, needle, string_length (needle)); }
4169  
4170      Vector_index_t find_vector (Vector_index_t a, Vector_t const &needle) const
4171      { return Vector_find_raw (it(), a, needle.it()->m_table, needle.it()->m_nentries); }
4172  
4173      Vector_index_t find_vector (Vector_index_t a, Vector_t const *needle) const
4174      { return Vector_find_raw (it(), a, needle->it()->m_table, needle->it()->m_nentries); }
4175  
4176  #if Vector_DIRECT_RECURSION == 0
4177      Vector_index_t find (Vector_index_t a, oType const *needle, Vector_cnt_t n) const
4178      { return Vector_find_raw (it(), a, needle, n); }
4179  
4180      Vector_index_t find (Vector_index_t a, oType const *needle) const
4181      { return Vector_find_raw (it(), a, needle, string_length (needle)); }
4182  
4183      Vector_index_t find (Vector_index_t a, Vector_t const &needle) const
4184      { return Vector_find_raw (it(), a, needle.it()->m_table, needle.it()->m_nentries); }
4185  
4186      Vector_index_t find (Vector_index_t a, Vector_t const *needle) const
4187      { return Vector_find_raw (it(), a, needle->it()->m_table, needle->it()->m_nentries); }
4188  #endif
4189  
4190      /* rFind family */
4191  
4192      Vector_index_t rfind  (oTypeParam needle) const
4193      { return Vector_rfind (it(), -1, needle); }
4194  
4195      Vector_index_t rfind_raw  (oType const *needle, Vector_cnt_t n) const
4196      { return Vector_rfind_raw (it(), -1, needle, n); }
4197  
4198      Vector_index_t rfind_string (oType const *needle) const
4199      { return Vector_rfind_raw (it(), -1, needle, string_length (needle)); }
4200  
4201      Vector_index_t rfind_vector (Vector_t const &needle) const
4202      { return Vector_rfind_raw (it(), -1, needle.it()->m_table, needle.it()->m_nentries); }
4203  
4204      Vector_index_t rfind_vector (Vector_t const *needle) const
4205      { return Vector_rfind_raw (it(), -1, needle->it()->m_table, needle->it()->m_nentries); }
4206  
4207  #if Vector_DIRECT_RECURSION == 0
4208      Vector_index_t rfind (oType const *needle, Vector_cnt_t n) const
4209      { return Vector_rfind_raw (it(), -1, needle, n); }
4210  
4211      Vector_index_t rfind (oType const *needle) const
4212      { return Vector_rfind_raw (it(), -1, needle, string_length (needle)); }
4213  
4214      Vector_index_t rfind (Vector_t const &needle) const
4215      { return Vector_rfind_raw (it(), -1, needle.it()->m_table, needle.it()->m_nentries); }
4216  
4217      Vector_index_t rfind (Vector_t const *needle) const
4218      { return Vector_rfind_raw (it(), -1, needle->it()->m_table, needle->it()->m_nentries); }
4219  #endif
4220  
4221      Vector_index_t rfind  (Vector_index_t a, oTypeParam needle) const
4222      { return Vector_rfind (it(), a, needle); }
4223  
4224      Vector_index_t rfind_raw  (Vector_index_t a, oType const *needle, Vector_cnt_t n) const
4225      { return Vector_rfind_raw (it(), a, needle, n); }
4226  
4227      Vector_index_t rfind_string  (Vector_index_t a, oType const *needle) const
4228      { return Vector_rfind_raw (it(), a, needle, string_length (needle)); }
4229  
4230      Vector_index_t rfind_vector (Vector_index_t a, Vector_t const &needle) const
4231      { return Vector_rfind_raw (it(), a, needle.it()->m_table, needle.it()->m_nentries); }
4232  
4233      Vector_index_t rfind_vector (Vector_index_t a, Vector_t const *needle) const
4234      { return Vector_rfind_raw (it(), a, needle->it()->m_table, needle->it()->m_nentries); }
4235  
4236  #if Vector_DIRECT_RECURSION == 0
4237      Vector_index_t rfind (Vector_index_t a, oType const *needle, Vector_cnt_t n) const
4238      { return Vector_rfind_raw (it(), a, needle, n); }
4239  
4240      Vector_index_t rfind (Vector_index_t a, oType const *needle) const
4241      { return Vector_rfind_raw (it(), a, needle, string_length (needle)); }
4242  
4243      Vector_index_t rfind (Vector_index_t a, Vector_t const &needle) const
4244      { return Vector_rfind_raw (it(), a, needle.it()->m_table, needle.it()->m_nentries); }
4245  
4246      Vector_index_t rfind (Vector_index_t a, Vector_t const *needle) const
4247      { return Vector_rfind_raw (it(), a, needle->it()->m_table, needle->it()->m_nentries); }
4248  #endif
4249  
4250  
4251      /* is_equal_at family
4252       * FIXME: Some functions are missing.  Compare to overwrite.  This is because
4253       *        the C function has a bad calling convention.  This must be fixed in
4254       *        the next major release of Erwin. */
4255  
4256      bool is_equal_at_raw (Vector_index_t a, oType const *b, Vector_cnt_t n) const
4257      { return Global_ERWIN_TO_BOOL(Vector_is_equal_at (it(), a, b, n)); }
4258  
4259      bool is_equal_at_string (Vector_index_t a, oType const *b) const
4260      { return Global_ERWIN_TO_BOOL(Vector_is_equal_at (it(), a, b, string_length (b))); }
4261  
4262      bool is_equal_at_vector (Vector_index_t a, Vector_t const &b) const
4263      { return Global_ERWIN_TO_BOOL(Vector_is_equal_at (it(), a, b.it()->m_table, b.it()->m_nentries)); }
4264  
4265      bool is_equal_at_vector (Vector_index_t a, Vector_t const *b) const
4266      { return Global_ERWIN_TO_BOOL(Vector_is_equal_at (it(), a, b->it()->m_table, b->it()->m_nentries)); }
4267  
4268  #if Vector_DIRECT_RECURSION == 0
4269      bool is_equal_at (Vector_index_t a, oType const *b, Vector_cnt_t n) const
4270      { return Global_ERWIN_TO_BOOL(Vector_is_equal_at (it(), a, b, n)); }
4271  
4272      bool is_equal_at (Vector_index_t a, oType const *b) const
4273      { return Global_ERWIN_TO_BOOL(Vector_is_equal_at (it(), a, b, string_length (b))); }
4274  
4275      bool is_equal_at (Vector_index_t a, Vector_t const &b) const
4276      { return Global_ERWIN_TO_BOOL(Vector_is_equal_at (it(), a, b.it()->m_table, b.it()->m_nentries)); }
4277  
4278      bool is_equal_at (Vector_index_t a, Vector_t const *b) const
4279      { return Global_ERWIN_TO_BOOL(Vector_is_equal_at (it(), a, b->it()->m_table, b->it()->m_nentries)); }
4280  #endif
4281  
4282      Vector_index_t find_if (Vector_feature_t feature, bool inverted Vector_DEFAULT_ARG(true))
4283      {
4284          return Vector_find_if (it(), 0, feature, inverted);
4285      }
4286  
4287      Vector_index_t find_if (Vector_index_t start, Vector_feature_t feature, bool inverted Vector_DEFAULT_ARG(true))
4288      {
4289          return Vector_find_if (it(), start, feature, inverted);
4290      }
4291  
4292      Vector_index_t rfind_if (Vector_feature_t feature, bool inverted Vector_DEFAULT_ARG(true))
4293      {
4294          return Vector_rfind_if (it(), -1, feature, inverted);
4295      }
4296  
4297      Vector_index_t rfind_if (Vector_index_t start, Vector_feature_t feature, bool inverted Vector_DEFAULT_ARG(true))
4298      {
4299          return Vector_rfind_if (it(), start, feature, inverted);
4300      }
4301  
4302      /* Convenience functions */
4303  
4304      Vector_index_t find_if_not (Vector_feature_t feature, bool inverted Vector_DEFAULT_ARG(true))
4305      {
4306          return Vector_find_if (it(), 0, feature, !inverted);
4307      }
4308  
4309      Vector_index_t find_if_not (Vector_index_t start, Vector_feature_t feature, bool inverted Vector_DEFAULT_ARG(true))
4310      {
4311          return Vector_find_if (it(), start, feature, !inverted);
4312      }
4313  
4314      Vector_index_t rfind_if_not (Vector_feature_t feature, bool inverted Vector_DEFAULT_ARG(true))
4315      {
4316          return Vector_rfind_if (it(), -1, feature, !inverted);
4317      }
4318  
4319      Vector_index_t rfind_if_not (Vector_index_t start, Vector_feature_t feature, bool inverted Vector_DEFAULT_ARG(true))
4320      {
4321          return Vector_rfind_if (it(), start, feature, !inverted);
4322      }
4323  
4324      /*  Trimming */
4325  
4326      Vector_t &ltrim_if (Vector_feature_t feature, bool inverted Vector_DEFAULT_ARG(true))
4327      {
4328          Vector_ltrim_if (it(), feature, inverted);
4329          return *this;
4330      }
4331  
4332      Vector_t &ltrim_if_not (Vector_feature_t feature, bool inverted Vector_DEFAULT_ARG(true))
4333      {
4334          Vector_ltrim_if (it(), feature, !inverted);
4335          return *this;
4336      }
4337  
4338      Vector_t &rtrim_if (Vector_feature_t feature, bool inv Vector_DEFAULT_ARG (true))
4339      {
4340          Vector_rtrim_if (it(), feature, inv);
4341          return *this;
4342      }
4343  
4344      Vector_t &rtrim_if_not (Vector_feature_t feature, bool inv Vector_DEFAULT_ARG (true))
4345      {
4346          Vector_rtrim_if (it(), feature, !inv);
4347          return *this;
4348      }
4349  
4350      Vector_t &trim_if (Vector_feature_t feature, bool inv Vector_DEFAULT_ARG (true))
4351      {
4352          Vector_trim_if (it(), feature, inv);
4353          return *this;
4354      }
4355  
4356      Vector_t &trim_if_not (Vector_feature_t feature, bool inv Vector_DEFAULT_ARG (true))
4357      {
4358          Vector_trim_if (it(), feature, !inv);
4359          return *this;
4360      }
4361  
4362      /* Mapping */
4363  
4364      Vector_t &map (Vector_map_t fmap)
4365      {
4366          Vector_map (it(), fmap);
4367          return *this;
4368      }
4369  
4370  #IFEQ (isChar,1)
4371      Vector_t &ltrim (void)
4372      { Vector_ltrim (it()); return *this; }
4373  
4374      Vector_t &rtrim (void)
4375      { Vector_rtrim (it()); return *this; }
4376  
4377      Vector_t &trim  (void)
4378      { Vector_trim (it()); return *this; }
4379  
4380      Vector_t &chomp (void)
4381      { Vector_chomp (it()); return *this; }
4382  
4383      Vector_t &to_upper (void)
4384      {
4385          Vector_to_upper (it());
4386          return *this;
4387      }
4388  
4389      Vector_t &to_lower (void)
4390      {
4391          Vector_to_lower (it());
4392          return *this;
4393      }
4394  
4395      /* Additional operators for appending strings to the vector. */
4396  #ifdef ERWIN_UNSIGNED_LONG_LONG
4397      Vector_t &operator<< (ERWIN_UNSIGNED_LONG_LONG  a)  { format("%Lu",a); return *this; }
4398      Vector_t &operator<< (ERWIN_LONG_LONG           a)  { format("%Ld",a); return *this; }
4399  #endif
4400  
4401      Vector_t &operator<< (unsigned long  a)    { format("%lu",a);          return *this; }
4402      Vector_t &operator<< (signed long    a)    { format("%ld",a);          return *this; }
4403      Vector_t &operator<< (unsigned int   a)    { format("%u", a);          return *this; }
4404      Vector_t &operator<< (signed int     a)    { format("%d", a);          return *this; }
4405  
4406      Vector_t &operator<< (double         a)    { format("%g", a);          return *this; }
4407  
4408      Vector_t &operator<< (void *         a)    { format("%p", a);          return *this; }
4409  
4410      Vector_t &operator<< (unsigned short a)    { return operator<< ((unsigned int) a); }
4411      Vector_t &operator<< (signed short   a)    { return operator<< ((signed   int) a); }
4412  
4413      Vector_t &operator<< (bool a)
4414      {
4415          append((oType const *)(a ? "true" : "false"));
4416          return *this;
4417      }
4418  
4419      /* The stringify() family is for creating vectors from printing values.
4420       * It was mainly added to make it easier to handle different types of
4421       * integers without the user needing to know the exact type when using
4422       * printf-like functions.
4423       *
4424       *    fprintf (f, "Number of things: %s\n", +stringify(thing_count));
4425       *
4426       * The stringify() family is also suited for lazy people who want to do
4427       * something like:
4428       *
4429       *   #define _S   +VChar::stringify
4430       *   #define _F   +VChar().format
4431       *
4432       * _S is especially handy when the precise integer type is unknown and you
4433       * must print via C-style formating.  E.g. you can use:
4434       *
4435       *    fprintf (f, "Number of things: %s\n", _S(thing_count));
4436       *
4437       * Here, no need to bother about %d vs. %ld vs. %Ld etc.
4438       *
4439       * Furthermore, it was decided against having a Qt-like parameter list
4440       * as arg()), because the primary usage is different: for arg(),
4441       * you specify the print width in the arg() call while for stringify(),
4442       * it is cleaner to specify it in the printf-like format string:
4443       *
4444       *      printf ("Length: %10s bytes\n", _S(count));
4445       * vs.
4446       *      QString("Length: %1 byets\n").arg(count,10)
4447       *
4448       * So the width argument is less important for stringify().
4449       * However, we do want easy access to the base argument for ints,
4450       * so we move the width (and precision) to the end of the parameter
4451       * list, and have the base as second for integer arguments.
4452       *
4453       * Further, we want the other options arguments to make it easy to
4454       * quote on the fly.  The options argument will be just after the
4455       * base (if present).
4456       *
4457       *      printf ("Key and value are: %s=%s",
4458       *          _S(key), _S(value, FO_QUOTE_C_STRING));
4459       *
4460       *      printf ("Count: %s", _S(count, 10, FO_USE_SEP_(' ')));
4461       *
4462       * For integers, a base of 0 will be interpreted like 10.
4463       *
4464       * Also note that zero padding of numbers can be achievd by increasing
4465       * the precision instead of the width:
4466       *
4467       *      _S(5)          = "5"
4468       *      _S(5,10,0,5,0) = "    5"
4469       *      _S(5,10,0,0,5) = "00005"
4470       *
4471       * For 'double' variant of stringify(), the char argument which may
4472       * be 'e', 'f', 'g', or 'a' will take the place of the base argument.
4473       */
4474  
4475  #ifdef ERWIN_UNSIGNED_LONG_LONG
4476      static Vector_t stringify (
4477          ERWIN_UNSIGNED_LONG_LONG a, int base = 0, int options = 0, int width = 0, int prec = -1)
4478      {
4479          return Vector_t().format(options | Global_FO_RADIX(base), "%*.*Lu", width, prec, a);
4480      }
4481  
4482      static Vector_t stringify (
4483          ERWIN_LONG_LONG a, int base = 0, int options = 0, int width = 0, int prec = -1)
4484      {
4485          return Vector_t().format(options | Global_FO_RADIX(base), "%*.*Ld", width, prec, a);
4486      }
4487  #endif
4488  
4489      static Vector_t stringify (
4490          unsigned long a, int base = 0, int options = 0, int width = 0, int prec = -1)
4491      {
4492          return Vector_t().format(options | Global_FO_RADIX(base), "%*.*lu", width, prec, a);
4493      }
4494  
4495      static Vector_t stringify (
4496          long a, int base = 0, int options = 0, int width = 0, int prec = -1)
4497      {
4498          return Vector_t().format(options | Global_FO_RADIX(base), "%*.*ld", width, prec, a);
4499      }
4500  
4501      static Vector_t stringify (
4502          unsigned a, int base = 0, int options = 0, int width = 0, int prec = -1)
4503      {
4504          return stringify((unsigned long)a,base,options,width,prec);
4505      }
4506  
4507      static Vector_t stringify (
4508          int a, int base = 0, int options = 0, int width = 0, int prec = -1)
4509      {
4510          return stringify((long)a,base,options,width,prec);
4511      }
4512  
4513      static Vector_t stringify (
4514          unsigned short a, int base = 0, int options = 0, int width = 0, int prec = -1)
4515      {
4516          return stringify((unsigned long)a,base,options,width,prec);
4517      }
4518  
4519      static Vector_t stringify (
4520          short a, int base = 0, int options = 0, int width = 0, int prec = -1)
4521      {
4522          return stringify((long)a,base,options,width,prec);
4523      }
4524  
4525  #if 0
4526      /* Must be explicitly typecast to int to make clear code. */
4527      static Vector_t stringify (
4528          unsigned char a, int base = 0, int options = 0, int width = 0, int prec = -1)
4529      {
4530          return stringify((unsigned long)a,base,options,width,prec);
4531      }
4532  
4533      static Vector_t stringify (
4534          signed char a, int base = 0, int options = 0, int width = 0, int prec = -1)
4535      {
4536          return stringify((long)a,base,options,width,prec);
4537      }
4538  #endif
4539  
4540      static Vector_t stringify (
4541          double a, int base = 0, int options = 0, int width = 0, int prec = -1)
4542      {
4543          return Vector_t().format(options | Global_FO_RADIX(base), "%*.*lg", width, prec, a);
4544      }
4545  
4546      static Vector_t stringify (char a, int options = 0, int width = 0)
4547      {
4548          return Vector_t().format(options, "%*c", width, a);
4549      }
4550  
4551      static Vector_t stringify (char const *a, int options = 0, int width = 0, int prec = -1)
4552      {
4553          return Vector_t().format(options, "%*.*s", width, prec, a);
4554      }
4555  
4556  #ifdef ERWIN_WIDE_CHARACTERS
4557      static Vector_t stringify (wchar_t const *a, int options = 0, int width = 0, int prec = -1)
4558      {
4559          return Vector_t().format(options, "%*.*ls", width, prec, a);
4560      }
4561  #endif
4562  
4563      static Vector_t stringify (Vector_t const *a, int options = 0, int width = 0, int prec = -1)
4564      {
4565          return Vector_t().format(options | Global_FO_VECTOR, "%*.*s",
4566              width, prec, (char const *)a);
4567              /* We are using %s to pass the vector to be able to use the precision
4568               * with a gcc warning.  Both %p and %s honour the Global_FO_VECTOR flag. */
4569      }
4570  
4571      static Vector_t stringify (Vector_t const &a, int options = 0, int width = 0, int prec = -1)
4572      {
4573          return stringify(&a, options, width, prec);
4574      }
4575  
4576      static Vector_t stringify (bool a, int options = 0, int width = 0, int prec = -1)
4577      {
4578          return stringify((Tchar const *)(a ? "true" : "false"), options, width, prec);
4579      }
4580  
4581  #ENDIF /* IFEQ (isChar,1) */
4582  
4583  #IFEQ (isChar,1)
4584      int fread (FILE *fileptr, Vector_cnt_t max_count Vector_DEFAULT_ARG(-1))
4585      {
4586          return Vector_fread (it(), fileptr, max_count);
4587      }
4588  
4589      Vector_t &fgets (FILE *fileptr, Vector_cnt_t max_count Vector_DEFAULT_ARG(-1))
4590      {
4591          Vector_fgets (it(), fileptr, max_count);
4592          return *this;
4593      }
4594  
4595      Vector_index_t basename_index (void) const
4596      {
4597          return Vector_basename_index (it());
4598      }
4599  
4600      void basename_range (Vector_index_t &no1, Vector_cnt_t &length) const
4601      {
4602          Vector_basename_range (&no1, &length, it());
4603      }
4604  
4605      Vector_t &append_directory (Vector_t const &other)
4606      {
4607          Vector_append_directory (it(), other.it());
4608          return *this;
4609      }
4610  
4611      Vector_t &append_directory (Vector_t const *other)
4612      {
4613          Vector_append_directory (it(), other->it());
4614          return *this;
4615      }
4616  
4617      Vector_t &append_basename (Vector_t const &other)
4618      {
4619          Vector_append_basename (it(), other.it());
4620          return *this;
4621      }
4622  
4623      Vector_t &append_basename (Vector_t const *other)
4624      {
4625          Vector_append_basename (it(), other->it());
4626          return *this;
4627      }
4628  
4629      Vector_t &append_config_file_name (
4630          oType const *progname,
4631          bool local Vector_DEFAULT_ARG(false))
4632      {
4633          Vector_append_config_file_name (it(), progname, local);
4634          return *this;
4635      }
4636  
4637  
4638  #if Vector_NO_FORMAT == 0
4639      Vector_t &format  (Tchar const *, ...) ATTR_FORMAT_PRINTF  (2, 3);
4640      Vector_t &vformat (Tchar const *, va_list) ATTR_FORMAT_VPRINTF (2);
4641  
4642      /* functions with option argument: */
4643      Vector_t &format  (unsigned long, Tchar const *, ...)     ATTR_FORMAT_PRINTF  (3, 4);
4644      Vector_t &vformat (unsigned long, Tchar const *, va_list) ATTR_FORMAT_VPRINTF (3);
4645  
4646      /* function with returned info */
4647      Vector_t &format  (Vector_format_info_t *, Tchar const *, ...)      ATTR_FORMAT_PRINTF  (3, 4);
4648      Vector_t &vformat (Vector_format_info_t *, Tchar const *, va_list)  ATTR_FORMAT_VPRINTF (3);
4649  
4650      /* functions with returned info and option argument: */
4651      Vector_t &format  (Vector_format_info_t *, unsigned long, Tchar const *, ...)     ATTR_FORMAT_PRINTF  (4, 5);
4652      Vector_t &vformat (Vector_format_info_t *, unsigned long, Tchar const *, va_list) ATTR_FORMAT_VPRINTF (4);
4653  
4654  #if Global_ERWIN_GLOBAL_ERRNO
4655      static bool format_quoted () ATTR_DEPRECATED;
4656      static Vector_index_t format_pos () ATTR_DEPRECATED;
4657  #endif
4658  
4659  #endif /* Vector_NO_FORMAT */
4660  #ENDIF /* IFEQ (isChar,1) */
4661  
4662      Vector_t &make_gap (Vector_index_t a, Vector_cnt_t b)
4663      {
4664          Vector_make_gap (it(), a, b);
4665          return *this;
4666      }
4667  
4668      Vector_t &make_gap (Vector_index_t a, oTypeTouched x, Vector_cnt_t b)
4669      {
4670          Vector_make_gap_with (it(), a, x, b);
4671          return *this;
4672      }
4673  
4674      /* compatibility function */
4675      Vector_t &make_gap_with (Vector_index_t a, oTypeTouched x, Vector_cnt_t b)
4676      {
4677          return make_gap (a, x, b);
4678      }
4679  
4680      oTypeResult zero (void) const
4681      { return Vector_zero (it()); }
4682  
4683      /* Overwrite family */
4684  
4685      Vector_t &overwrite (
4686          Vector_index_t i,
4687          Vector_t const *a,
4688          Vector_index_t ia,
4689          Vector_cnt_t n)
4690      {
4691          Vector_overwrite (it(), i, a->it(), ia, n);
4692          return *this;
4693      }
4694  
4695      Vector_t &overwrite (
4696          Vector_index_t i,
4697          Vector_t const &a,
4698          Vector_index_t ia,
4699          Vector_cnt_t n)
4700      {
4701          Vector_overwrite (it(), i, a.it(), ia, n);
4702          return *this;
4703      }
4704  
4705      Vector_t &overwrite_raw (Vector_index_t i, oType const *a, Vector_cnt_t n)
4706      {
4707          Vector_overwrite_raw (it(), i, a, n);
4708          return *this;
4709      }
4710  
4711      Vector_t &overwrite_string (Vector_index_t i, oType const *a)
4712      {
4713          Vector_overwrite_string (it(), i, a);
4714          return *this;
4715      }
4716  
4717      Vector_t &overwrite_vector (Vector_index_t i, Vector_t const *a)
4718      {
4719          Vector_overwrite_vector (it(), i, a->it());
4720          return *this;
4721      }
4722  
4723      Vector_t &overwrite_vector (Vector_index_t i, Vector_t const &a)
4724      {
4725          Vector_overwrite_vector (it(), i, a.it());
4726          return *this;
4727      }
4728  
4729  #IFEQ(oType,oTypeVar)
4730      Vector_t &overwrite_flags (Vector_index_t i, oType const *a, Vector_cnt_t n, bool dealloc, bool docopy)
4731      {
4732          Vector_overwrite_flags (it(), i, a, n, dealloc, docopy);
4733          return *this;
4734      }
4735  #ENDIF
4736  
4737  #if Vector_DIRECT_RECURSION == 0
4738      Vector_t &overwrite (Vector_index_t i, oType const *a, Vector_cnt_t n)
4739      {
4740          Vector_overwrite_raw (it(), i, a, n);
4741          return *this;
4742      }
4743  
4744      Vector_t &overwrite (Vector_index_t i, oType const *a)
4745      {
4746          Vector_overwrite_string (it(), i, a);
4747          return *this;
4748      }
4749  
4750      Vector_t &overwrite (Vector_index_t i, Vector_t const *a)
4751      {
4752          Vector_overwrite_vector (it(), i, a->it());
4753          return *this;
4754      }
4755  
4756      Vector_t &overwrite (Vector_index_t i, Vector_t const &a)
4757      {
4758          Vector_overwrite_vector (it(), i, a.it());
4759          return *this;
4760      }
4761  #endif
4762  
4763      /* Insert family */
4764  
4765      Vector_t &insert (Vector_index_t i, oTypeTouched a)
4766      {
4767          Vector_insert (it(), i, a);
4768          return *this;
4769      }
4770  
4771      Vector_t &insert_raw (Vector_index_t i, oType const *a, Vector_cnt_t n)
4772      {
4773          Vector_insert_raw (it(), i, a, n);
4774          return *this;
4775      }
4776  
4777      Vector_t &insert_no_copy (Vector_index_t i, oTypeVar const *a, Vector_cnt_t n)
4778      {
4779          Vector_insert_no_copy (it(), i, a, n);
4780          return *this;
4781      }
4782  
4783      Vector_t &insert_string (Vector_index_t i, oType const *a)
4784      {
4785          Vector_insert_string (it(), i, a);
4786          return *this;
4787      }
4788  
4789      Vector_t &insert_vector (Vector_index_t i, Vector_t const *a)
4790      {
4791          Vector_insert_vector (it(), i, a->it());
4792          return *this;
4793      }
4794  
4795      Vector_t &insert_vector (Vector_index_t i, Vector_t const &a)
4796      {
4797          Vector_insert_vector (it(), i, a.it());
4798          return *this;
4799      }
4800  
4801      Vector_t &insert_subvector (
4802          Vector_index_t i,
4803          Vector_t const *a,
4804          Vector_index_t b Vector_DEFAULT_ARG (0),
4805          Vector_cnt_t c Vector_DEFAULT_ARG (-1),
4806          Global_ERWIN_BOOL d Vector_DEFAULT_ARG (Global_ERWIN_TRUE))
4807      {
4808          Vector_insert_subvector (it(), i, a->it(), b, c, d ? Global_ERWIN_TRUE : Global_ERWIN_FALSE);
4809          return *this;
4810      }
4811  
4812      Vector_t &insert_subvector (
4813          Vector_index_t i,
4814          Vector_t const &a,
4815          Vector_index_t b Vector_DEFAULT_ARG (0),
4816          Vector_cnt_t c Vector_DEFAULT_ARG (-1),
4817          Global_ERWIN_BOOL d Vector_DEFAULT_ARG (Global_ERWIN_TRUE))
4818      {
4819          Vector_insert_subvector (it(), i, a.it(), b, c, d ? Global_ERWIN_TRUE : Global_ERWIN_FALSE);
4820          return *this;
4821      }
4822  
4823  #if Vector_DIRECT_RECURSION == 0
4824      Vector_t &insert (
4825          Vector_index_t i,
4826          Vector_t const &a,
4827          Vector_index_t b,
4828          Vector_cnt_t c Vector_DEFAULT_ARG (-1),
4829          Global_ERWIN_BOOL d Vector_DEFAULT_ARG (Global_ERWIN_TRUE))
4830      {
4831          return insert_subvector (i, a, b, c, d);
4832      }
4833  
4834      Vector_t &insert (
4835          Vector_index_t i,
4836          Vector_t const *a,
4837          Vector_index_t b,
4838          Vector_cnt_t c Vector_DEFAULT_ARG (-1),
4839          Global_ERWIN_BOOL d Vector_DEFAULT_ARG (Global_ERWIN_TRUE))
4840      {
4841          return insert_subvector (i, a, b, c, d);
4842      }
4843  
4844      Vector_t &insert (Vector_index_t i, oType const *a, Vector_cnt_t n)
4845      {
4846          Vector_insert_raw (it(), i, a, n);
4847          return *this;
4848      }
4849  
4850      Vector_t &insert (Vector_index_t i, oType const *a)
4851      {
4852          Vector_insert_string (it(), i, a);
4853          return *this;
4854      }
4855  
4856      Vector_t &insert (Vector_index_t i, Vector_t const *a)
4857      {
4858          Vector_insert_vector (it(), i, a->it());
4859          return *this;
4860      }
4861                                         
4862      Vector_t &insert (Vector_index_t i, Vector_t const &a)
4863      {
4864          Vector_insert_vector (it(), i, a.it());
4865          return *this;
4866      }
4867  
4868  #endif
4869  
4870      Vector_cnt_t string_length (oType const *a) const
4871      {
4872          return Vector_string_length (it(), a);
4873      }
4874  
4875      Vector_t &ensure_size (Vector_cnt_t a)
4876      { Vector_ensure_size (it(), a); return *this; }
4877  
4878      Vector_t &ensure_size (Vector_cnt_t a, oTypeTouched b)
4879      { Vector_ensure_size_with (it(), a, b); return *this; }
4880  
4881      Vector_t &set_size (Vector_cnt_t a)
4882      { Vector_set_size (it(), a); return *this; }
4883  
4884      Vector_t &set_size (Vector_cnt_t a, oTypeTouched b)
4885      { Vector_set_size_with (it(), a, b); return *this; }
4886  
4887      int ensure_table_size (Vector_cnt_t a)
4888      { return Vector_ensure_table_size (it(), a); }
4889  
4890      Vector_element_ptr_t as_array (void) const
4891      { return Vector_as_array (it()); }
4892  
4893      Vector_element_ptr_t as_open_array (void) const
4894      { return Vector_as_open_array (it()); }
4895  
4896      Vector_element_ptr_t as_array_detach (void)
4897      { return Vector_as_array_detach (it()); }
4898  
4899      Vector_t &ensure_heap_storage(void)
4900      {
4901          Vector_ensure_heap_storage (it());
4902          return *this;
4903      }
4904  
4905      bool has_heap_storage() const
4906      {
4907          return Vector_has_heap_storage (it());
4908      }
4909  
4910      static Vector_cnt_t inline_store_cnt()
4911      {
4912          return  Vector_inline_store_cnt();
4913      }
4914  
4915      Vector_element_ptr_t as_open_array_detach (void)
4916      { return Vector_as_open_array_detach (it()); }
4917  
4918  #IFEQ (isChar,1)
4919      Vector_element_ptr_t operator+(Vector_index_t i)
4920      { return  nth_ptr_char (i); }
4921  
4922  #if ERWIN_IGNORE_BROKEN_MS_COMPILER
4923      oType const *operator+(Vector_index_t i) const
4924      { return  (oType const *)((Vector_class *)this)->nth_ptr_char (i); }
4925  #endif
4926  
4927      Vector_element_ref_t operator*()
4928      { return *nth_ptr_char (0); }
4929  
4930  #if ERWIN_IGNORE_BROKEN_MS_COMPILER
4931      oTypeResult operator*() const
4932      { return nth_char (0); }
4933  #endif
4934  
4935      Vector_element_ptr_t operator+() const
4936      { return as_array(); }
4937  
4938  #ELSE
4939  
4940      Vector_element_ptr_t operator+(Vector_index_t i)
4941      { return  nth_ptr_check (i); }
4942  
4943  #if ERWIN_IGNORE_BROKEN_MS_COMPILER
4944      oType const *operator+(Vector_index_t i) const
4945      { return  nth_ptr_check (i); }
4946  #endif
4947  
4948      Vector_element_ref_t operator*()
4949      { return *nth_ptr_check (0); }
4950  
4951  #if ERWIN_IGNORE_BROKEN_MS_COMPILER
4952      oTypeResult operator*() const
4953      { return nth (0); }
4954  #endif
4955  
4956      Vector_element_ptr_t operator+() const
4957      { return as_open_array(); }
4958          /* No 0-termination with non-charactor types.  That's consistent with using
4959           * nth_ptr_check here instead of nth_ptr_char for the isChar case. */
4960  
4961  #ENDIF
4962  
4963      Vector_t &make_heap(Vector_cmp_t f Vector_DEFAULT_ARG(Vector_CMP_T_NULL))
4964      {
4965          Vector_make_heap(it(), f);
4966          return *this;
4967      }
4968  
4969      Vector_index_t heap_left (Vector_index_t i) const
4970      {
4971          return Vector_heap_left(it(), i);
4972      }
4973  
4974      Vector_index_t heap_right (Vector_index_t i) const
4975      {
4976          return Vector_heap_right (it(), i);
4977      }
4978  
4979      Vector_index_t heap_father (Vector_index_t i) const
4980      {
4981          return Vector_heap_father (it(), i);
4982      }
4983  
4984      oTypeVar heap_extract (Vector_cmp_t f Vector_DEFAULT_ARG(Vector_CMP_T_NULL))
4985      {
4986          return Vector_heap_extract (it(), f);
4987      }
4988  
4989      Vector_t &heap_raise (Vector_index_t i, Vector_cmp_t f Vector_DEFAULT_ARG(Vector_CMP_T_NULL))
4990      {
4991          Vector_heap_raise (it(), i, f);
4992          return *this;
4993      }
4994  
4995      Vector_t &heap_sink (Vector_index_t i, Vector_cmp_t f Vector_DEFAULT_ARG(Vector_CMP_T_NULL))
4996      {
4997          Vector_heap_sink (it(), i, f);
4998          return *this;
4999      }
5000  
5001      Vector_t &heap_fix (Vector_index_t i, Vector_cmp_t f Vector_DEFAULT_ARG(Vector_CMP_T_NULL))
5002      {
5003          Vector_heap_fix (it(), i, f);
5004          return *this;
5005      }
5006  
5007      Vector_t &heap_insert (
5008          oTypeParam elem, Vector_cmp_t f Vector_DEFAULT_ARG(Vector_CMP_T_NULL))
5009      {
5010          Vector_heap_insert (it(), elem, f);
5011          return *this;
5012      }
5013  
5014      Vector_t &heap_erase (
5015          Vector_index_t i, Vector_cmp_t f Vector_DEFAULT_ARG(Vector_CMP_T_NULL))
5016      {
5017          Vector_heap_erase (it(), i, f);
5018          return *this;
5019      }
5020  
5021      Vector_t &heap_sort (Vector_cmp_t f Vector_DEFAULT_ARG(Vector_CMP_T_NULL))
5022      {
5023          Vector_heap_sort (it(), f);
5024          return *this;
5025      }
5026  
5027  
5028      Vector_t &qsort (Vector_cmp_t f Vector_DEFAULT_ARG(Vector_CMP_T_NULL))
5029      {
5030          Vector_qsort (it(), f);
5031          return *this;
5032      }
5033  
5034      Vector_t &sort  (Vector_cmp_t f Vector_DEFAULT_ARG(Vector_CMP_T_NULL))
5035      {
5036          Vector_sort (it(), f);
5037          return *this;
5038      }
5039  
5040  
5041      Vector_index_t  bfind (oTypeParam a, Vector_cmp_t f = NULL) const
5042      {
5043          return Vector_bfind (it(), a, f);
5044      }
5045  
5046      Global_hashval_t hash_raw (void) const
5047      {
5048          return Vector_hash_raw (it());
5049      }
5050  
5051      Global_hashval_t hash (void) const
5052      {
5053          return Vector_hash (it());
5054      }
5055  
5056      void init_iterator (Vector_index_t *a) const
5057      {
5058          Vector_init_iterator (it(), a);
5059      }
5060  
5061      bool next_iteration (Vector_index_t *a, oType *b) const
5062      {
5063          return Global_ERWIN_TO_BOOL(Vector_next_iteration  (it(), a, b));
5064      }
5065  
5066      bool next_iteration_ptr (Vector_index_t *a, oTypeVar **b)
5067      {
5068          return Global_ERWIN_TO_BOOL(Vector_next_iteration_ptr  (it(), a, b));
5069      }
5070  
5071      bool next_iteration_ptr (Vector_index_t *a, oTypeVar const **b) const
5072      {
5073          return Global_ERWIN_TO_BOOL(Vector_next_iteration_ptr_const  (it(), a, b));
5074      }
5075  
5076      void init_iterator_reverse (Vector_index_t *a) const
5077      {
5078          Vector_init_iterator_reverse (it(), a);
5079      }
5080  
5081      bool next_iteration_reverse (Vector_index_t *a, oType *b) const
5082      {
5083          return Global_ERWIN_TO_BOOL(Vector_next_iteration_reverse  (it(), a, b));
5084      }
5085  
5086      bool next_iteration_ptr_reverse (Vector_index_t *a, oTypeVar **b)
5087      {
5088          return Global_ERWIN_TO_BOOL(Vector_next_iteration_ptr_reverse  (it(), a, b));
5089      }
5090  
5091      bool next_iteration_ptr_reverse (Vector_index_t *a, oTypeVar const **b) const
5092      {
5093          return Global_ERWIN_TO_BOOL(Vector_next_iteration_ptr_const_reverse  (it(), a, b));
5094      }
5095  
5096      Vector_t &shrink(bool tight = true)
5097      {
5098          Vector_shrink(it(), tight ? Global_ERWIN_TRUE : Global_ERWIN_FALSE);
5099          return *this;
5100      }
5101      Vector_t &clear ()
5102      { Vector_clear (it()); return *this; }
5103  
5104      Vector_t &clear_keep (Vector_cnt_t n)
5105      { Vector_clear_keep (it(),n); return *this; }
5106  
5107      Vector_t &clear_no_resize ()
5108      { Vector_clear_no_resize (it()); return *this; }
5109  
5110  #IFEQ(oType,oTypeVar)
5111      static void delete_array(Vector_element_ptr_t array)
5112      {
5113          Vector_delete_array(array);
5114      }
5115  #ENDIF
5116  
5117  #IFEQ(oType,oTypeVar)
5118      Vector_t &clear (bool a, bool b=true)
5119      { Vector_clear_flags (it(), a, b); return *this; }
5120  #ENDIF
5121  
5122  #ifdef Vector_INLINE__NENTRIES
5123      Vector_cnt_t  nentries () const
5124      {
5125  #ifdef Vector_ALLOW_NULL
5126          if (this == NULL) return 0;
5127  #endif
5128          return m_nentries;
5129      }
5130  #else
5131      Vector_cnt_t nentries () const
5132      { return Vector_nentries (it()); }
5133  #endif
5134  
5135      bool empty () const
5136      { return nentries() == 0; }
5137  
5138      bool non_empty () const
5139      { return !empty(); }
5140  
5141      Vector_cnt_t table_size () const
5142      { return Vector_table_size (it()); }
5143  
5144      int cmp (Vector_t const *other,           
5145               Vector_cmp_t fcmp Vector_DEFAULT_ARG(Vector_CMP_T_NULL)) const
5146      {
5147          if (this == NULL)
5148              return other == NULL ? 0 : -1;
5149          if (other == NULL)
5150              return +1;
5151          return Vector_cmp(it(), other->it(), fcmp);
5152      }
5153  
5154      int cmp (Vector_t const &other,
5155               Vector_cmp_t cmp_func Vector_DEFAULT_ARG(Vector_CMP_T_NULL)) const
5156      {
5157          return cmp (&other, cmp_func);
5158      }
5159  
5160      int priority_cmp (Vector_t const *other,
5161               Vector_cmp_t fcmp Vector_DEFAULT_ARG(Vector_CMP_T_NULL)) const
5162      {
5163          if (this == NULL)
5164              return other == NULL ? 0 : -1;
5165          if (other == NULL)
5166              return +1;
5167          return Vector_priority_cmp(it(), other->it(), fcmp);
5168      }
5169  
5170      int priority_cmp (Vector_t const &other,
5171               Vector_cmp_t fcmp Vector_DEFAULT_ARG(Vector_CMP_T_NULL)) const
5172      {
5173          return priority_cmp (&other, fcmp);
5174      }
5175  
5176      bool operator== (Vector_t const &b) const
5177      { return cmp(b,Vector_CMP_T_NULL) == 0; } /* see cmp() */
5178  
5179      bool operator== (Vector_t const *b) const
5180      { return cmp(b,Vector_CMP_T_NULL) == 0; } /* see cmp() */
5181  
5182      bool operator!= (Vector_t const &b) const
5183      { return cmp(b,Vector_CMP_T_NULL) != 0; } /* see cmp() */
5184  
5185      bool operator!= (Vector_t const *b) const
5186      { return cmp(b,Vector_CMP_T_NULL) != 0; } /* see cmp() */
5187  
5188      bool operator<= (Vector_t const &b) const
5189      { return cmp(b,Vector_CMP_T_NULL) <= 0; } /* see cmp() */
5190  
5191      bool operator<= (Vector_t const *b) const
5192      { return cmp(b,Vector_CMP_T_NULL) <= 0; } /* see cmp() */
5193  
5194      bool operator>= (Vector_t const &b) const
5195      { return cmp(b,Vector_CMP_T_NULL) >= 0; } /* see cmp() */
5196  
5197      bool operator>= (Vector_t const *b) const
5198      { return cmp(b,Vector_CMP_T_NULL) >= 0; } /* see cmp() */
5199  
5200      bool operator<  (Vector_t const &b) const
5201      { return cmp(b,Vector_CMP_T_NULL) < 0; }  /* see cmp() */
5202  
5203      bool operator<  (Vector_t const *b) const
5204      { return cmp(b,Vector_CMP_T_NULL) < 0; }  /* see cmp() */
5205  
5206      bool operator>  (Vector_t const &b) const
5207      { return cmp(b,Vector_CMP_T_NULL) > 0; }  /* see cmp() */
5208  
5209      bool operator>  (Vector_t const *b) const
5210      { return cmp(b,Vector_CMP_T_NULL) > 0; }  /* see cmp() */
5211  
5212      Vector_t &swap (Vector_index_t a, Vector_index_t b)
5213      {
5214          Vector_swap (it(), a, b);
5215          return *this;
5216      }
5217  
5218      bool locate (Vector_index_t &index, oTypeParam element, int how) const
5219      {
5220          return Global_ERWIN_TO_BOOL(Vector_locate (&index, it(), element, Vector_CMP_T_NULL, how));
5221      }
5222  
5223      bool locate (Vector_index_t &index,
5224                   oTypeParam element,
5225                   Vector_cmp_t fcmp Vector_DEFAULT_ARG(Vector_CMP_T_NULL),
5226                   int how Vector_DEFAULT_ARG(0)) const
5227      {
5228          return Global_ERWIN_TO_BOOL(Vector_locate (&index, it(), element, fcmp, how));
5229      }
5230  
5231  /*--END-CLASS--*/
5232  
5233  #endif /* defined __cplusplus */
5234  };
5235  
5236  #undef Vector_LOCAL_WRAPPER
5237  
5238  #ifdef __cplusplus
5239  
5240  #IFEQ(0,0)
5241  
5242  /* For nasty code like:
5243   *
5244   *    extern "C" {
5245   *    #include <erwin/erwin.h>
5246   *    ...
5247   *    }
5248   *
5249   * Yes, some people do such things.
5250   */
5251  extern "C++" {
5252  /* some nasty global functions that are useful e.g. for forall.  Note that these
5253   * are not local to one vector but will be overloaded by all different vector
5254   * instantiations. */
5255  
5256  ERWIN_WRAPPER
5257  Vector_t *Global_erwin_ptr_of(Vector_t *x) { return x;  }
5258  
5259  ERWIN_WRAPPER
5260  Vector_t *Global_erwin_ptr_of(Vector_t &x) { return &x; }
5261  
5262  ERWIN_WRAPPER
5263  Vector_t const *Global_erwin_ptr_const_of (Vector_t const *x) { return x;  }
5264  
5265  ERWIN_WRAPPER
5266  Vector_t const *Global_erwin_ptr_const_of (Vector_t const &x) { return &x; }
5267  }
5268  
5269  #ELSE
5270  
5271  #ifndef Global_erwin_ptr_of
5272  #define Global_erwin_ptr_of(x) x
5273  #endif
5274  
5275  #ifndef Global_erwin_ptr_const_of
5276  #define Global_erwin_ptr_const_of(x) x
5277  #endif
5278  
5279  #ENDIF
5280  
5281  /* Forall macros for C++ */
5282  #ifndef Global_vector_forall
5283  #define Global_vector_forall(v,i,h)                                      \
5284              for(Global_erwin_ptr_const_of(v)->init_iterator(&(i));       \
5285                  Global_erwin_ptr_const_of(v)->next_iteration(&(i),&(h)); \
5286                  /* no stepper */)
5287  #endif
5288  
5289  
5290  #ifndef Global_vector_forall_ptr
5291  #define Global_vector_forall_ptr(v,i,h)                                \
5292              for(Global_erwin_ptr_of(v)->init_iterator(&(i));           \
5293                  Global_erwin_ptr_of(v)->next_iteration_ptr(&(i),&(h)); \
5294                  /* no stepper */)
5295  #endif
5296  
5297  
5298  #ifndef Global_vector_forall_ptr_const
5299  #define Global_vector_forall_ptr_const(v,i,h)                                \
5300              for(Global_erwin_ptr_const_of(v)->init_iterator(&(i));           \
5301                  Global_erwin_ptr_const_of(v)->next_iteration_ptr(&(i),&(h)); \
5302                  /* no stepper */)
5303  #endif
5304  
5305  
5306  #ifndef Global_vector_forall_keys
5307  #define Global_vector_forall_keys(v,i) \
5308              for((i)=0; ((Vector_index_t)(i)) < Global_erwin_ptr_const_of(v)->nentries(); (i)++)
5309  #endif
5310  
5311  
5312  #ifndef Global_vector_forall_values
5313  #define Global_vector_forall_values(v,h)                                                         \
5314              for(Vector_index_t ERWIN_GENSYM(erwin_local_j)=-1;                                   \
5315                  Global_erwin_ptr_const_of(v)->next_iteration(&ERWIN_GENSYM(erwin_local_j),&(h)); \
5316                  /* no stepper */)
5317  #endif
5318  
5319  
5320  #ifndef Global_vector_forall_values_ptr
5321  #define Global_vector_forall_values_ptr(v,h)                                                   \
5322              for(Vector_index_t ERWIN_GENSYM(erwin_local_j)=-1;                                            \
5323                  Global_erwin_ptr_of(v)->next_iteration_ptr(&ERWIN_GENSYM(erwin_local_j),&(h)); \
5324                  /* no stepper */)
5325  #endif
5326  
5327  
5328  #ifndef Global_vector_forall_values_ptr_const
5329  #define Global_vector_forall_values_ptr_const(v,h)                                                   \
5330              for(Vector_index_t ERWIN_GENSYM(erwin_local_j)=-1;                                       \
5331                  Global_erwin_ptr_const_of(v)->next_iteration_ptr(&ERWIN_GENSYM(erwin_local_j),&(h)); \
5332                  /* no stepper */)
5333  #endif
5334  
5335  
5336  #ifndef Global_vector_forall_reverse
5337  #define Global_vector_forall_reverse(v,i,h)                                      \
5338              for(Global_erwin_ptr_const_of(v)->init_iterator_reverse(&(i));       \
5339                  Global_erwin_ptr_const_of(v)->next_iteration_reverse(&(i),&(h)); \
5340                  /* no stepper */)
5341  #endif
5342  
5343  
5344  #ifndef Global_vector_forall_ptr_reverse
5345  #define Global_vector_forall_ptr_reverse(v,i,h)                                \
5346              for(Global_erwin_ptr_of(v)->init_iterator_reverse(&(i));           \
5347                  Global_erwin_ptr_of(v)->next_iteration_ptr_reverse(&(i),&(h)); \
5348                  /* no stepper */)
5349  #endif
5350  
5351  
5352  #ifndef Global_vector_forall_ptr_const_reverse
5353  #define Global_vector_forall_ptr_const_reverse(v,i,h)                                \
5354              for(Global_erwin_ptr_const_of(v)->init_iterator_reverse(&(i));           \
5355                  Global_erwin_ptr_const_of(v)->next_iteration_ptr_reverse(&(i),&(h)); \
5356                  /* no stepper */)
5357  #endif
5358  
5359  
5360  #ifndef Global_vector_forall_keys_reverse
5361  #define Global_vector_forall_keys_reverse(v,i) \
5362              for((i)=Global_erwin_ptr_const_of(v)->nentries()-1; ((Vector_index_t)(i)) >= 0; (i)--)
5363  #endif
5364  
5365  
5366  #ifndef Global_vector_forall_values_reverse
5367  #define Global_vector_forall_values_reverse(v,h)                                          \
5368              for(Vector_index_t ERWIN_GENSYM(erwin_local_j)=Global_erwin_ptr_const_of(v)->nentries(); \
5369                  Global_erwin_ptr_const_of(v)                                              \
5370                       ->next_iteration_reverse(&ERWIN_GENSYM(erwin_local_j),&(h));         \
5371                  /* no stepper */)
5372  #endif
5373  
5374  #ifndef Global_vector_forall_values_ptr_reverse
5375  #define Global_vector_forall_values_ptr_reverse(v,h)                                 \
5376              for(Vector_index_t ERWIN_GENSYM(erwin_local_j)=                          \
5377                      Global_erwin_ptr_const_of(v)->nentries();                        \
5378                  Global_erwin_ptr_of(v)                                               \
5379                      ->next_iteration_ptr_reverse(&ERWIN_GENSYM(erwin_local_j),&(h)); \
5380                  /* no stepper */)
5381  #endif
5382  
5383  #ifndef Global_vector_forall_values_ptr_const_reverse
5384  #define Global_vector_forall_values_ptr_const_reverse(v,h)                           \
5385              for(Vector_index_t ERWIN_GENSYM(erwin_local_j)=                          \
5386                      Global_erwin_ptr_const_of(v)->nentries();                        \
5387                  Global_erwin_ptr_const_of(v)                                         \
5388                      ->next_iteration_ptr_reverse(&ERWIN_GENSYM(erwin_local_j),&(h)); \
5389                  /* no stepper */)
5390  #endif
5391  
5392  #endif /* defined __cplusplus */
5393  
5394  /* ********************************************************************** */
5395  /* Inline implementations: */
5396  
5397  #if Vector_POSITION_POINTER
5398  
5399  ERWIN_WRAPPER Vector_index_t *Vector_pos_ptr (Vector_t *);
5400  ERWIN_WRAPPER Vector_index_t *Vector_pos_ptr (Vector_t *x)                   { return &x->m_pos; }
5401  
5402  ERWIN_WRAPPER Vector_index_t  Vector_pos     (Vector_t *);
5403  ERWIN_WRAPPER Vector_index_t  Vector_pos     (Vector_t *x)                   { return x->m_pos;  }
5404  
5405  ERWIN_WRAPPER void            Vector_set_pos (Vector_t *,  Vector_index_t);
5406  ERWIN_WRAPPER void            Vector_set_pos (Vector_t *x, Vector_index_t y) { x->m_pos= y;      }
5407  
5408  #endif
5409  
5410  #ifdef Vector_INLINE__NTH
5411  
5412  ERWIN_STATIC_INLINE
5413  oTypeResult Vector_nth (Vector_t const* self, Vector_index_t idx)
5414  {
5415      return self->m_table[idx];
5416  }
5417  
5418  #endif
5419  
5420  #ifdef Vector_INLINE__NENTRIES
5421  
5422  ERWIN_STATIC_INLINE
5423  Vector_cnt_t Vector_nentries (Vector_t const *self)
5424  {
5425      return self->m_nentries;
5426  }
5427  
5428  ERWIN_STATIC_INLINE
5429  Global_ERWIN_BOOL Vector_empty (Vector_t const *self)
5430  {
5431      return self->m_nentries == 0;
5432  }
5433  
5434  #endif
5435  
5436  #endif /* ERWINMM_Vector_ErwinHExt */

Index

Stoppt die Vorratsdatenspeicherung
November 26th, 2007
Comments? Suggestions? Corrections? You can drop me a line.
zpentrabvagiktu@theiling.de
Schwerpunktpraxis