+/**en
+ @brief Concatenate two plists.
+
+ The mplist__conc () function concatenates plist $TAIL at the end of
+ plist $PLIST and return $PLIST. If $TAIL is empty, return $PLIST
+ without modifying it. */
+
+MPlist *
+mplist__conc (MPlist *plist, MPlist *tail)
+{
+ MPlist *pl;
+
+ if (MPLIST_TAIL_P (tail))
+ return plist;
+ MPLIST_DO (pl, plist);
+ MPLIST_KEY (pl) = MPLIST_KEY (tail);
+ MPLIST_VAL (pl) = MPLIST_VAL (tail);
+ if (MPLIST_KEY (pl)->managing_key)
+ M17N_OBJECT_REF (MPLIST_VAL (pl));
+ tail = MPLIST_NEXT (tail);
+ MPLIST_NEXT (pl) = tail;
+ M17N_OBJECT_REF (tail);
+ return plist;
+}
+
+/*=*/
+/**en
+ @brief Discard a property at the beginning of a property list.
+
+ The mplist__pop_unref () function removes a property at the
+ beginning of property list $PLIST, and if the property value is a
+ managed object, unref it. As a result, the second key and value
+ of the original $PLIST become the first of those of the new
+ $PLIST. */
+
+void
+mplist__pop_unref (MPlist *plist)
+{
+ MSymbol key;
+ void *val;
+
+ if (MPLIST_TAIL_P (plist))
+ return;
+ key = MPLIST_KEY (plist);
+ val = mplist_pop (plist);
+ if (key->managing_key)
+ M17N_OBJECT_UNREF (val);
+}
+
+/**en
+ @brief Search for an element of an alist represented by a plist.
+
+ The mplist__assq () function treats $PLIST as an association list
+ (elements are plists (key is #Mplist) whose first element is a
+ symbol (key is #Msymbol)), and find an element whose first element
+ has key #Msymbol and value $KEY.
+
+ Non-plist elements of $PLIST are ignored.
+
+ @return
+ This function returns a found element or NULL if no element
+ matches with $KEY. */
+
+MPlist *
+mplist__assq (MPlist *plist, MSymbol key)
+{
+ MPLIST_DO (plist, plist)
+ if (MPLIST_PLIST_P (plist))
+ {
+ MPlist *pl = MPLIST_PLIST (plist);
+
+ if (MPLIST_SYMBOL_P (pl) && MPLIST_SYMBOL (pl) == key)
+ return plist;
+ }
+ return NULL;
+}
+