/* MIT License * * Copyright (c) 2025 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. */ // IWYU pragma: private #ifndef _i_template #define _i_template #ifndef STC_TEMPLATE_H_INCLUDED #define STC_TEMPLATE_H_INCLUDED #define _c_MEMB(name) c_JOIN(Self, name) #define _c_DEFTYPES(macro, SELF, ...) macro(SELF, __VA_ARGS__) #define _m_value _c_MEMB(_value) #define _m_key _c_MEMB(_key) #define _m_mapped _c_MEMB(_mapped) #define _m_rmapped _c_MEMB(_rmapped) #define _m_raw _c_MEMB(_raw) #define _m_keyraw _c_MEMB(_keyraw) #define _m_iter _c_MEMB(_iter) #define _m_result _c_MEMB(_result) #define _m_node _c_MEMB(_node) #define c_OPTION(flag) ((i_opt) & (flag)) #define c_declared (1<<0) #define c_no_atomic (1<<1) #define c_arc2 (1<<2) #define c_no_clone (1<<3) #define c_no_hash (1<<4) #define c_use_cmp (1<<5) #define c_use_eq (1<<6) #define c_cmpclass (1<<7) #define c_keyclass (1<<8) #define c_valclass (1<<9) #define c_keypro (1<<10) #define c_valpro (1<<11) #endif #if defined i_rawclass // [deprecated] #define i_cmpclass i_rawclass #endif #if defined T && !defined i_type #define i_type T #endif #if defined i_type && c_NUMARGS(i_type) > 1 #define Self c_GETARG(1, i_type) #define i_key c_GETARG(2, i_type) #if c_NUMARGS(i_type) == 3 #if defined _i_is_map #define i_val c_GETARG(3, i_type) #else #define i_opt c_GETARG(3, i_type) #endif #elif c_NUMARGS(i_type) == 4 #define i_val c_GETARG(3, i_type) #define i_opt c_GETARG(4, i_type) #endif #elif !defined Self && defined i_type #define Self i_type #elif !defined Self #define Self c_JOIN(_i_prefix, i_tag) #endif #if defined i_aux && c_NUMARGS(i_aux) == 2 // shorthand for defining i_aux AND i_allocator as a one-liner combo. #define _i_aux_alloc #define _i_aux_def c_GETARG(1, i_aux) aux; #undef i_allocator // override: #define i_allocator c_GETARG(2, i_aux) #elif defined i_aux #define _i_aux_def i_aux aux; #else #define _i_aux_def #endif #if c_OPTION(c_declared) #define i_declared #endif #if c_OPTION(c_no_hash) #define i_no_hash #endif #if c_OPTION(c_use_cmp) #define i_use_cmp #endif #if c_OPTION(c_use_eq) #define i_use_eq #endif #if c_OPTION(c_no_clone) || defined _i_is_arc #define i_no_clone #endif #if c_OPTION(c_keyclass) #define i_keyclass i_key #endif #if c_OPTION(c_valclass) #define i_valclass i_val #endif #if c_OPTION(c_cmpclass) #define i_cmpclass i_key #define i_use_cmp #endif #if c_OPTION(c_keypro) #define i_keypro i_key #endif #if c_OPTION(c_valpro) #define i_valpro i_val #endif #if defined i_keypro #define i_keyclass i_keypro #define i_cmpclass c_JOIN(i_keypro, _raw) #endif #if defined i_cmpclass #define i_keyraw i_cmpclass #if !(defined i_key || defined i_keyclass) #define i_key i_cmpclass #endif #elif defined i_keyclass && !defined i_keyraw // Special: When only i_keyclass is defined, also define i_cmpclass to the same. // Do not define i_keyraw here, otherwise _from() / _toraw() is expected to exist. #define i_cmpclass i_key #endif // Bind to i_key "class members": _clone, _drop, _from and _toraw (when conditions are met). #if defined i_keyclass #ifndef i_key #define i_key i_keyclass #endif #if !defined i_keyclone && !defined i_no_clone #define i_keyclone c_JOIN(i_keyclass, _clone) #endif #ifndef i_keydrop #define i_keydrop c_JOIN(i_keyclass, _drop) #endif #if !defined i_keyfrom && defined i_keyraw #define i_keyfrom c_JOIN(i_keyclass, _from) #endif #if !defined i_keytoraw && defined i_keyraw #define i_keytoraw c_JOIN(i_keyclass, _toraw) #endif #endif // Define when container has support for sorting (cmp) and linear search (eq) #if defined i_use_cmp || defined i_cmp || defined i_less #define _i_has_cmp #endif #if defined i_use_cmp || defined i_cmp || defined i_use_eq || defined i_eq #define _i_has_eq #endif // Bind to i_cmpclass "class members": _cmp, _eq and _hash (when conditions are met). #if defined i_cmpclass #if !(defined i_cmp || defined i_less) && (defined i_use_cmp || defined _i_sorted) #define i_cmp c_JOIN(i_cmpclass, _cmp) #endif #if !defined i_eq && (defined i_use_eq || defined i_hash || defined _i_is_hash) #define i_eq c_JOIN(i_cmpclass, _eq) #endif #if !(defined i_hash || defined i_no_hash) #define i_hash c_JOIN(i_cmpclass, _hash) #endif #endif #if !defined i_key #error "No i_key defined" #elif defined i_keyraw && !(c_OPTION(c_cmpclass) || defined i_keytoraw) #error "If i_cmpclass / i_keyraw is defined, i_keytoraw must be defined too" #elif !defined i_no_clone && (defined i_keyclone ^ defined i_keydrop) #error "Both i_keyclone and i_keydrop must be defined, if any (unless i_no_clone defined)." #elif defined i_from || defined i_drop #error "i_from / i_drop not supported. Use i_keyfrom/i_keydrop" #elif defined i_keyto || defined i_valto #error i_keyto / i_valto not supported. Use i_keytoraw / i_valtoraw #elif defined i_keyraw && defined i_use_cmp && !defined _i_has_cmp #error "For smap / sset / pqueue, i_cmp or i_less must be defined when i_keyraw is defined." #endif // Fill in missing i_eq, i_less, i_cmp functions with defaults. #if !defined i_eq && defined i_cmp #define i_eq(x, y) (i_cmp(x, y)) == 0 #elif !defined i_eq #define i_eq(x, y) *x == *y // works for integral types #endif #if !defined i_less && defined i_cmp #define i_less(x, y) (i_cmp(x, y)) < 0 #elif !defined i_less #define i_less(x, y) *x < *y // works for integral types #endif #if !defined i_cmp && defined i_less #define i_cmp(x, y) (i_less(y, x)) - (i_less(x, y)) #endif #if !(defined i_hash || defined i_no_hash) #define i_hash c_default_hash #endif #define i_no_emplace #ifndef i_tag #define i_tag i_key #endif #if !defined i_keyfrom #define i_keyfrom c_default_clone #else #undef i_no_emplace #endif #ifndef i_keyraw #define i_keyraw i_key #endif #ifndef i_keytoraw #define i_keytoraw c_default_toraw #endif #ifndef i_keyclone #define i_keyclone c_default_clone #endif #ifndef i_keydrop #define i_keydrop c_default_drop #endif #if defined _i_is_map // ---- process hashmap/sortedmap value i_val, ... ---- #if defined i_valpro #define i_valclass i_valpro #define i_valraw c_JOIN(i_valpro, _raw) #endif #ifdef i_valclass #ifndef i_val #define i_val i_valclass #endif #if !defined i_valclone && !defined i_no_clone #define i_valclone c_JOIN(i_valclass, _clone) #endif #ifndef i_valdrop #define i_valdrop c_JOIN(i_valclass, _drop) #endif #if !defined i_valfrom && defined i_valraw #define i_valfrom c_JOIN(i_valclass, _from) #endif #if !defined i_valtoraw && defined i_valraw #define i_valtoraw c_JOIN(i_valclass, _toraw) #endif #endif #ifndef i_val #error "i_val* must be defined for maps" #elif defined i_valraw && !defined i_valtoraw #error "If i_valraw is defined, i_valtoraw must be defined too" #elif !defined i_no_clone && (defined i_valclone ^ defined i_valdrop) #error "Both i_valclone and i_valdrop must be defined, if any" #endif #if !defined i_valfrom #define i_valfrom c_default_clone #else #undef i_no_emplace #endif #ifndef i_valraw #define i_valraw i_val #endif #ifndef i_valtoraw #define i_valtoraw 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_is_map #ifndef i_val #define i_val i_key #endif #ifndef i_valraw #define i_valraw i_keyraw #endif #endif // STC_TEMPLATE_H_INCLUDED