/* MIT License * * Copyright (c) 2023 Tyge Løvset * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #ifndef _i_template #define _i_template #ifndef STC_TEMPLATE_H_INCLUDED #define STC_TEMPLATE_H_INCLUDED #define _cx_Self i_type #define _cx_MEMB(name) c_PASTE(_cx_Self, name) #define _cx_DEFTYPES(macro, SELF, ...) c_EXPAND(macro(SELF, __VA_ARGS__)) #define _cx_value _cx_MEMB(_value) #define _cx_key _cx_MEMB(_key) #define _cx_mapped _cx_MEMB(_mapped) #define _cx_raw _cx_MEMB(_raw) #define _cx_keyraw _cx_MEMB(_keyraw) #define _cx_iter _cx_MEMB(_iter) #define _cx_result _cx_MEMB(_result) #define _cx_node _cx_MEMB(_node) #endif #ifndef i_type #define i_type c_PASTE(_i_prefix, i_tag) #endif #ifndef i_allocator #define i_allocator c #endif #ifndef i_malloc #define i_malloc c_PASTE(i_allocator, _malloc) #define i_calloc c_PASTE(i_allocator, _calloc) #define i_realloc c_PASTE(i_allocator, _realloc) #define i_free c_PASTE(i_allocator, _free) #endif #if !(defined i_key || defined i_key_str || defined i_key_ssv || \ defined i_keyclass || defined i_keyboxed) #if defined _i_ismap #error "i_key* must be defined for maps" #endif #if defined i_val_str #define i_key_str i_val_str #endif #if defined i_val_ssv #define i_key_ssv i_val_ssv #endif #if defined i_valboxed #define i_keyboxed i_valboxed #endif #if defined i_valclass #define i_keyclass i_valclass #endif #if defined i_val #define i_key i_val #endif #if defined i_valraw #define i_keyraw i_valraw #endif #if defined i_valclone #define i_keyclone i_valclone #endif #if defined i_valfrom #define i_keyfrom i_valfrom #endif #if defined i_valto #define i_keyto i_valto #endif #if defined i_valdrop #define i_keydrop i_valdrop #endif #endif #if c_option(c_is_forward) #define i_is_forward #endif #if c_option(c_no_cmp) #define i_no_cmp #endif #if c_option(c_no_hash) #define i_no_hash #endif #if c_option(c_no_emplace) #define i_no_emplace #endif #if c_option(c_native_cmp) #define i_cmp_native #endif #if c_option(c_no_clone) || defined _i_carc #define i_no_clone #endif #if defined i_key_str #define i_keyclass cstr #define i_rawclass ccharptr #ifndef i_tag #define i_tag str #endif #elif defined i_key_ssv #define i_keyclass cstr #define i_rawclass csview #define i_keyfrom cstr_from_sv #define i_keyto cstr_sv #define i_eq csview_eq #ifndef i_tag #define i_tag ssv #endif #elif defined i_keyboxed #define i_keyclass i_keyboxed #define i_rawclass c_PASTE(i_keyboxed, _raw) #ifndef i_no_cmp #define i_eq c_PASTE(i_keyboxed, _raw_eq) #endif #endif #if defined i_rawclass #define i_keyraw i_rawclass #elif defined i_keyclass && !defined i_keyraw #define i_rawclass i_key #endif #ifdef i_keyclass #define i_key i_keyclass #ifndef i_keyclone #define i_keyclone c_PASTE(i_key, _clone) #endif #if !defined i_keyto && defined i_keyraw #define i_keyto c_PASTE(i_key, _toraw) #endif #if !defined i_keyfrom && defined i_keyraw #define i_keyfrom c_PASTE(i_key, _from) #endif #ifndef i_keydrop #define i_keydrop c_PASTE(i_key, _drop) #endif #endif #ifdef i_rawclass #if !(defined i_cmp || defined i_no_cmp) #define i_cmp c_PASTE(i_keyraw, _cmp) #endif #if !(defined i_hash || defined i_no_hash || defined i_no_cmp) #define i_hash c_PASTE(i_keyraw, _hash) #endif #endif #if !defined i_keyraw && !defined i_no_clone #if !defined i_keyfrom && defined i_keyclone #define i_keyfrom i_keyclone #elif !defined i_keyclone && defined i_keyfrom #define i_keyclone i_keyfrom #endif #endif #ifndef i_no_cmp #if defined i_cmp || defined i_less || defined i_cmp_native #define _i_has_cmp #endif #if defined i_eq || defined i_cmp_native #define _i_has_eq #endif #endif #if !defined i_key #error "No i_key or i_val defined" #elif defined i_keyraw ^ defined i_keyto #error "Both i_keyraw/i_valraw and i_keyto/i_valto must be defined, if any" #elif !defined i_no_clone && (defined i_keyclone ^ defined i_keydrop) #error "Both i_keyclone/i_valclone and i_keydrop/i_valdrop must be defined, if any" #elif defined i_from || defined i_drop #error "i_from / i_drop not supported. Define i_keyfrom/i_valfrom and/or i_keydrop/i_valdrop instead" #elif defined i_keyraw && defined _i_ishash && !(defined i_hash && (defined _i_has_cmp || defined i_eq)) #error "For cmap/cset, both i_hash and i_eq (or i_less or i_cmp) must be defined when i_keyraw is defined." #elif defined i_keyraw && (defined _i_ismap || defined _i_isset || defined _i_ispque) && !defined _i_has_cmp #error "For csmap/csset/cpque, i_cmp or i_less must be defined when i_keyraw is defined." #endif #ifndef i_tag #define i_tag i_key #endif #ifndef i_keyraw #define i_keyraw i_key #endif #ifndef i_keyfrom #define i_keyfrom c_default_clone #else #define i_has_emplace #endif #ifndef i_keyto #define i_keyto c_default_toraw #endif #ifndef i_keyclone #define i_keyclone c_default_clone #endif #ifndef i_keydrop #define i_keydrop c_default_drop #endif #ifndef i_no_cmp // i_eq, i_less, i_cmp #if !defined i_eq && (defined i_cmp || defined i_less) #define i_eq(x, y) !(i_cmp(x, y)) #elif !defined i_eq #define i_eq(x, y) *x == *y #endif #if defined i_cmp && defined i_less #error "Only one of i_cmp and i_less may be defined" #elif defined i_cmp #define i_less(x, y) (i_cmp(x, y)) < 0 #elif !defined i_less #define i_less(x, y) *x < *y #endif #ifndef i_cmp #define i_cmp(x, y) (i_less(y, x)) - (i_less(x, y)) #endif #endif #if !defined i_hash && (!(defined _i_cbox || defined _i_carc) || defined i_cmp_native) #define i_hash c_default_hash #endif #if defined _i_ismap // ---- process cmap/csmap value i_val, ... ---- #ifdef i_val_str #define i_valclass cstr #define i_valraw const char* #elif defined i_val_ssv #define i_valclass cstr #define i_valraw csview #define i_valfrom cstr_from_sv #define i_valto cstr_sv #elif defined i_valboxed #define i_valclass i_valboxed #define i_valraw c_PASTE(i_valboxed, _raw) #endif #ifdef i_valclass #define i_val i_valclass #ifndef i_valclone #define i_valclone c_PASTE(i_val, _clone) #endif #if !defined i_valto && defined i_valraw #define i_valto c_PASTE(i_val, _toraw) #endif #if !defined i_valfrom && defined i_valraw #define i_valfrom c_PASTE(i_val, _from) #endif #ifndef i_valdrop #define i_valdrop c_PASTE(i_val, _drop) #endif #endif #if !defined i_valraw && !defined i_no_clone #if !defined i_valfrom && defined i_valclone #define i_valfrom i_valclone #elif !defined i_valclone && defined i_valfrom #define i_valclone i_valfrom #endif #endif #ifndef i_val #error "i_val* must be defined for maps" #elif defined i_valraw ^ defined i_valto #error "Both i_valraw and i_valto must be defined, if any" #elif !defined i_no_clone && (defined i_valclone ^ defined i_valdrop) #error "Both i_valclone and i_valdrop must be defined, if any" #endif #ifndef i_valraw #define i_valraw i_val #endif #ifndef i_valfrom #define i_valfrom c_default_clone #else #define i_has_emplace #endif #ifndef i_valto #define i_valto c_default_toraw #endif #ifndef i_valclone #define i_valclone c_default_clone #endif #ifndef i_valdrop #define i_valdrop c_default_drop #endif #endif // !_i_ismap #ifndef i_val #define i_val i_key #endif #ifndef i_valraw #define i_valraw i_keyraw #endif #ifndef i_has_emplace #define i_no_emplace #endif #endif