1 /*
2  * collection.h - Common interface for collection, sequence, and dictionary.
3  *
4  *   Copyright (c) 2007-2020  Shiro Kawai  <shiro@acm.org>
5  *
6  *   Redistribution and use in source and binary forms, with or without
7  *   modification, are permitted provided that the following conditions
8  *   are met:
9  *
10  *   1. Redistributions of source code must retain the above copyright
11  *      notice, this list of conditions and the following disclaimer.
12  *
13  *   2. Redistributions in binary form must reproduce the above copyright
14  *      notice, this list of conditions and the following disclaimer in the
15  *      documentation and/or other materials provided with the distribution.
16  *
17  *   3. Neither the name of the authors nor the names of its contributors
18  *      may be used to endorse or promote products derived from this
19  *      software without specific prior written permission.
20  *
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
27  *   TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28  *   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29  *   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30  *   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31  *   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 /* This file is included from gauche.h */
35 
36 #ifndef GAUCHE_COLLECTION_H
37 #define GAUCHE_COLLECTION_H
38 
39 /*
40  * Class stuff
41  */
42 
43 SCM_CLASS_DECL(Scm_CollectionClass);
44 SCM_CLASS_DECL(Scm_SequenceClass);
45 SCM_CLASS_DECL(Scm_DictionaryClass);
46 SCM_CLASS_DECL(Scm_OrderedDictionaryClass);
47 
48 #define SCM_CLASS_COLLECTION         (&Scm_CollectionClass)
49 #define SCM_CLASS_SEQUENCE           (&Scm_SequenceClass)
50 #define SCM_CLASS_DICTIONARY         (&Scm_DictionaryClass)
51 #define SCM_CLASS_ORDERED_DICTIONARY (&Scm_OrderedDictionaryClass)
52 
53 /* NB: we can't use SCM_EXTERN because Windows DLL can't use the address of
54    dllimport-ed variables as constants. */
55 extern ScmClass *Scm__OrderedDictionaryCPL[];
56 extern ScmClass *Scm__SequenceCPL[];
57 
58 #define SCM_CLASS_COLLECTION_CPL         (Scm__SequenceCPL+1)
59 #define SCM_CLASS_SEQUENCE_CPL           (Scm__SequenceCPL)
60 #define SCM_CLASS_DICTIONARY_CPL         (Scm__OrderedDictionaryCPL+2)
61 #define SCM_CLASS_ORDERED_DICTIONARY_CPL (Scm__OrderedDictionaryCPL)
62 
63 /*
64  * Sequence-related utilities
65  */
66 
67 /* Utility to check start/end range in string and vector operation */
68 #define SCM_CHECK_START_END(start, end, len)                            \
69     do {                                                                \
70         if ((start) < 0 || (start) > (len)) {                           \
71             Scm_Error("start argument out of range: %ld", (start));     \
72         }                                                               \
73         if ((end) < 0) (end) = (len);                                   \
74         else if ((end) > (len)) {                                       \
75             Scm_Error("end argument out of range: %ld", (end));         \
76         } else if ((end) < (start)) {                                   \
77             Scm_Error("end argument (%ld) must be greater than or "     \
78                       "equal to the start argument (%ld)",              \
79                       (end), (start));                                  \
80         }                                                               \
81     } while (0)
82 
83 /*
84  * Dictionary-related utilities
85  */
86 
87 /* "Dictionary" is a common base of hashtables and treemaps.
88    The dictionary feature is provided in two layers: The lower
89    layer treats key and value as an opaque data (intptr_t) and
90    implements the algorithm, while the upper layer treats ScmObj
91    keys and values. */
92 
93 /*
94  * Common part of the entry.  This is for the lower layer.
95  */
96 typedef struct ScmDictEntryRec {
97     const intptr_t key;
98     intptr_t  value;
99 } ScmDictEntry;
100 
101 /*
102  * Macros for the upper layer.
103  */
104 #define SCM_DICT_KEY(entry)   SCM_OBJ((entry)->key)
105 #define SCM_DICT_VALUE(entry) SCM_OBJ((entry)->value)
106 #define SCM_DICT_SET_VALUE(entry, val) \
107     SCM_OBJ((entry)->value = Scm__CheckDictValue(val, __FILE__, __LINE__))
108 
109 SCM_EXTERN intptr_t Scm__CheckDictValue(ScmObj val, const char *file, int line);
110 
111 /*
112  * Common operation argument for *Search functions
113  */
114 typedef enum {
115     SCM_DICT_GET,               /* returns ScmDictEntry* if found,
116                                    NULL otherwise. */
117     SCM_DICT_CREATE,            /* if not found, create a new entry.
118                                    always return ScmDictEntry*. */
119     SCM_DICT_DELETE             /* deletes found entry.  */
120 } ScmDictOp;
121 
122 /*
123  * Common flags for *Set functions
124  */
125 typedef enum {
126     SCM_DICT_NO_OVERWRITE = (1L<<0),/* do not overwrite the existing entry */
127     SCM_DICT_NO_CREATE    = (1L<<1) /* do not create new one if no match */
128 } ScmDictSetFlags;
129 
130 #endif /* GAUCHE_COLLECTION_H */
131 
132