@@ -4005,8 +4005,14 @@ reduces them without incurring seq initialization"
40054005
40064006; ; CLJS-3200: used by destructure macro for maps to reduce amount of repeated code
40074007; ; placed here because it needs apply and hash-map (only declared at this point)
4008- (defn --destructure-map [x]
4009- (if (implements? ISeq x) (apply cljs.core/hash-map x) x))
4008+ (defn --destructure-map [gmap]
4009+ (if (implements? ISeq gmap)
4010+ (if (next gmap)
4011+ (.createAsIfByAssoc PersistentArrayMap (to-array gmap))
4012+ (if (seq gmap)
4013+ (first gmap)
4014+ (.-EMPTY PersistentArrayMap)))
4015+ gmap))
40104016
40114017(defn vary-meta
40124018 " Returns an object of the same type and value as obj, with
@@ -7057,19 +7063,91 @@ reduces them without incurring seq initialization"
70577063 (let [cnt (/ (alength arr) 2 )]
70587064 (PersistentArrayMap. nil cnt arr nil )))))
70597065
7066+ (defn key-test [key other]
7067+ (cond
7068+ (identical? key other) true
7069+ (keyword-identical? key other) true
7070+ :else (= key other)))
7071+
7072+ (defn- ^boolean pam-dupes? [arr]
7073+ (loop [i 0 ]
7074+ (if (< i (alength arr))
7075+ (let [dupe? (loop [j 0 ]
7076+ (if (< j i)
7077+ (or
7078+ (key-test (aget arr i) (aget arr j))
7079+ (recur (+ 2 j)))
7080+ false ))]
7081+ (or dupe? (recur (+ 2 i))))
7082+ false )))
7083+
7084+ (defn- pam-new-size [arr]
7085+ (loop [i 0 n 0 ]
7086+ (if (< i (alength arr))
7087+ (let [dupe? (loop [j 0 ]
7088+ (if (< j i)
7089+ (or
7090+ (key-test (aget arr i) (aget arr j))
7091+ (recur (+ 2 j)))
7092+ false ))]
7093+ (recur (+ 2 i) (if dupe? n (+ n 2 ))))
7094+ n)))
7095+
7096+ (defn- pam-grow-seed-array [seed trailing]
7097+ (let [seed-cnt (dec (alength seed))
7098+ extra-kvs (seq trailing)
7099+ ret (make-array (+ seed-cnt (* 2 (count extra-kvs))))
7100+ ret (array-copy seed 0 ret 0 seed-cnt)]
7101+ (loop [i seed-cnt extra-kvs extra-kvs]
7102+ (if extra-kvs
7103+ (let [kv (first extra-kvs)]
7104+ (aset ret i (-key kv))
7105+ (aset ret (inc i) (-val kv))
7106+ (recur (+ 2 seed-cnt) (next extra-kvs)))
7107+ ret))))
7108+
70607109(set! (.-createAsIfByAssoc PersistentArrayMap)
7061- (fn [arr]
7062- (let [ret (array )]
7063- (loop [i 0 ]
7064- (when (< i (alength arr))
7065- (let [k (aget arr i)
7066- v (aget arr (inc i))
7067- idx (array-index-of ret k)]
7068- (if (== idx -1 )
7069- (doto ret (.push k) (.push v))
7070- (aset ret (inc idx) v)))
7071- (recur (+ i 2 ))))
7072- (PersistentArrayMap. nil (/ (alength ret) 2 ) ret nil ))))
7110+ (fn [init]
7111+ ; ; check trailing element
7112+ (let [len (alength init)
7113+ has-trailing? (== 1 (bit-and len 1 ))]
7114+ (if-not (or has-trailing? (pam-dupes? init))
7115+ (PersistentArrayMap. nil (/ len 2 ) init nil )
7116+ (.createAsIfByAssocComplexPath PersistentArrayMap init has-trailing?)))))
7117+
7118+ (set! (.-createAsIfByAssocComplexPath PersistentArrayMap)
7119+ (fn [init ^boolean has-trailing?]
7120+ (let [init (if has-trailing?
7121+ (pam-grow-seed-array init
7122+ ; ; into {} in case the final element is not a map but something conj-able
7123+ ; ; for parity with Clojure implementation of CLJ-2603
7124+ (into {} (aget init (dec (alength init)))))
7125+ init)
7126+ n (pam-new-size init)
7127+ len (alength init)]
7128+ (if (< n len)
7129+ (let [nodups (make-array n)]
7130+ (loop [i 0 m 0 ]
7131+ (if (< i len)
7132+ (let [dupe? (loop [j 0 ]
7133+ (if (< j m)
7134+ (or
7135+ (key-test (aget init i) (aget init j))
7136+ (recur (+ 2 j)))
7137+ false ))]
7138+ (if-not dupe?
7139+ (let [j (loop [j (- len 2 )]
7140+ (if (>= j i)
7141+ (if (key-test (aget init i) (aget init j))
7142+ j
7143+ (recur (- j 2 )))
7144+ j))]
7145+ (aset nodups m (aget init i))
7146+ (aset nodups (inc m) (aget init (inc j)))
7147+ (recur (+ 2 i) (+ 2 m)))
7148+ (recur (+ 2 i) m)))))
7149+ (PersistentArrayMap. nil (/ (alength nodups) 2 ) nodups nil ))
7150+ (PersistentArrayMap. nil (/ (alength init) 2 ) init nil )))))
70737151
70747152(es6-iterable PersistentArrayMap)
70757153
@@ -7170,12 +7248,6 @@ reduces them without incurring seq initialization"
71707248
71717249(declare create-inode-seq create-array-node-seq reset! create-node atom deref )
71727250
7173- (defn key-test [key other]
7174- (cond
7175- (identical? key other) true
7176- (keyword-identical? key other) true
7177- :else (= key other)))
7178-
71797251(defn- mask [hash shift]
71807252 (bit-and (bit-shift-right-zero-fill hash shift) 0x01f ))
71817253
@@ -8947,7 +9019,17 @@ reduces them without incurring seq initialization"
89479019 (let [arr (if (and (instance? IndexedSeq keyvals) (zero? (.-i keyvals)))
89489020 (.-arr keyvals)
89499021 (into-array keyvals))]
8950- (.createAsIfByAssoc PersistentArrayMap arr)))
9022+ (if (odd? (alength arr))
9023+ (throw (js/Error. (str " No value supplied for key: " (last arr))))
9024+ (.createAsIfByAssoc PersistentArrayMap arr))))
9025+
9026+ (defn seq-to-map-for-destructuring
9027+ " Builds a map from a seq as described in
9028+ https://clojure.org/reference/special_forms#keyword-arguments"
9029+ [s]
9030+ (if (next s)
9031+ (.createAsIfByAssoc PersistentArrayMap (to-array s))
9032+ (if (seq s) (first s) (.-EMPTY PersistentArrayMap))))
89519033
89529034(defn obj-map
89539035 " keyval => key val
0 commit comments