diff --git a/src/DataStructures/Traits/StrictSplDatastructureTrait.php b/src/DataStructures/Traits/StrictSplDatastructureTrait.php
new file mode 100644
index 0000000..982223a
--- /dev/null
+++ b/src/DataStructures/Traits/StrictSplDatastructureTrait.php
@@ -0,0 +1,422 @@
+
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+declare(strict_types=1);
+
+namespace OCC\Basics\DataStructures\Traits;
+
+use InvalidArgumentException;
+use OCC\Basics\DataStructures\Exceptions\InvalidDataTypeException;
+use OCC\Basics\DataStructures\StrictCollection;
+use OCC\Basics\Traits\TypeChecker;
+use OutOfRangeException;
+
+use function get_debug_type;
+use function iterator_to_array;
+use function serialize;
+use function sprintf;
+use function unserialize;
+
+/**
+ * The common interface of all type-sensitive, SPL-based datastructures.
+ *
+ * This extends all methods of the common interface of the Standard PHP Library
+ * [Doubly Linked List Datastructures](https://www.php.net/spl.datastructures)
+ * by type-checking to only allow specified data types on the list.
+ *
+ * @author Sebastian Meyer
+ * @package Basics\DataStructures
+ *
+ * @template AllowedType of mixed
+ */
+trait StrictSplDatastructureTrait
+{
+ use TypeChecker {
+ setAllowedTypes as protected;
+ }
+
+ /**
+ * Add/insert a new item at the specified offset.
+ *
+ * @param int $offset The offset where the new item is to be inserted
+ * @param AllowedType $value The new item for the offset
+ *
+ * @return void
+ *
+ * @throws InvalidDataTypeException if `$value` is not of allowed type
+ * @throws OutOfRangeException when `$offset` is out of bounds
+ *
+ * @api
+ */
+ public function add(int $offset, mixed $value): void
+ {
+ $this->offsetSet($offset, $value);
+ }
+
+ /**
+ * Append items at the end of the list.
+ *
+ * @param AllowedType ...$values One or more items to append
+ *
+ * @return void
+ *
+ * @throws InvalidDataTypeException if any `$values` is not of allowed type
+ *
+ * @api
+ */
+ public function append(mixed ...$values): void
+ {
+ /** @var array $values */
+ foreach ($values as $count => $value) {
+ if (!$this->hasAllowedType($value)) {
+ throw new InvalidDataTypeException(
+ sprintf(
+ 'Parameter %d must be an allowed type, %s given.',
+ $count + 1,
+ get_debug_type($value)
+ )
+ );
+ }
+ }
+ foreach ($values as $value) {
+ parent::push($value);
+ }
+ }
+
+ /**
+ * Clear the list of any items.
+ *
+ * @return void
+ *
+ * @api
+ */
+ public function clear(): void
+ {
+ while (!$this->isEmpty()) {
+ $this->pop();
+ }
+ $this->rewind();
+ }
+
+ /**
+ * Get the item at the specified index.
+ *
+ * @param int $offset The item's index
+ *
+ * @return AllowedType The item
+ *
+ * @throws OutOfRangeException when `$offset` is out of bounds
+ *
+ * @api
+ */
+ public function get(int $offset): mixed
+ {
+ return $this->offsetGet($offset);
+ }
+
+ /**
+ * Check if this can be considered a list.
+ *
+ * @return true Always TRUE (this exists only for compatibility reasons)
+ *
+ * @api
+ */
+ public function isList(): bool
+ {
+ return true;
+ }
+
+ /**
+ * Set the item at the specified offset.
+ *
+ * @param ?int $offset The offset being set or NULL to append
+ * @param AllowedType $value The new item for the offset
+ *
+ * @return void
+ *
+ * @throws InvalidDataTypeException if `$value` is not of allowed type
+ * @throws OutOfRangeException when `$offset` is out of bounds
+ *
+ * @api
+ */
+ public function offsetSet(mixed $offset, mixed $value): void
+ {
+ if (!$this->hasAllowedType($value)) {
+ throw new InvalidDataTypeException(
+ sprintf(
+ 'Parameter 2 must be an allowed type, %s given.',
+ get_debug_type($value)
+ )
+ );
+ }
+ /** @psalm-suppress PossiblyNullArgument */
+ parent::offsetSet($offset, $value);
+ }
+
+ /**
+ * Prepend items at the start of the list.
+ *
+ * @param AllowedType ...$values One or more items to prepend
+ *
+ * @return void
+ *
+ * @throws InvalidDataTypeException if `$value` is not of allowed type
+ *
+ * @api
+ */
+ public function prepend(mixed ...$values): void
+ {
+ /** @var array $values */
+ foreach ($values as $count => $value) {
+ if (!$this->hasAllowedType($value)) {
+ throw new InvalidDataTypeException(
+ sprintf(
+ 'Parameter %d must be an allowed type, %s given.',
+ $count + 1,
+ get_debug_type($value)
+ )
+ );
+ }
+ }
+ foreach ($values as $value) {
+ parent::unshift($value);
+ }
+ }
+
+ /**
+ * Push an item at the end of the list.
+ *
+ * @param AllowedType $value The item to push
+ *
+ * @return void
+ *
+ * @throws InvalidDataTypeException if `$value` is not of allowed type
+ *
+ * @api
+ */
+ public function push(mixed $value): void
+ {
+ if (!$this->hasAllowedType($value)) {
+ throw new InvalidDataTypeException(
+ sprintf(
+ 'Parameter 1 must be an allowed type, %s given.',
+ get_debug_type($value)
+ )
+ );
+ }
+ parent::push($value);
+ }
+
+ /**
+ * Remove an item from the list.
+ *
+ * @param int $offset The item's index
+ *
+ * @return void
+ *
+ * @throws OutOfRangeException when `$offset` is out of bounds
+ *
+ * @api
+ */
+ public function remove(int $offset): void
+ {
+ $this->offsetUnset($offset);
+ }
+
+ /**
+ * Get string representation of $this.
+ *
+ * @return string The string representation
+ *
+ * @internal
+ */
+ public function serialize(): string
+ {
+ return serialize($this->__serialize());
+ }
+
+ /**
+ * Set an item at the specified index.
+ *
+ * @param int $offset The item's index
+ * @param AllowedType $value The item
+ *
+ * @return void
+ *
+ * @throws InvalidDataTypeException if `$value` is not of allowed type
+ *
+ * @api
+ */
+ public function set(int $offset, mixed $value): void
+ {
+ $this->offsetSet($offset, $value);
+ }
+
+ /**
+ * Return array representation of list.
+ *
+ * @return array Array of list items
+ *
+ * @api
+ */
+ public function toArray(): array
+ {
+ return iterator_to_array($this, true);
+ }
+
+ /**
+ * Turn list into a type-sensitive collection.
+ *
+ * @return StrictCollection A type-sensitive collection of the list's items
+ *
+ * @api
+ */
+ public function toStrictCollection(): StrictCollection
+ {
+ $strictCollection = new StrictCollection($this->getAllowedTypes());
+ foreach ($this->toArray() as $offset => $value) {
+ $strictCollection[$offset] = $value;
+ }
+ return $strictCollection;
+ }
+
+ /**
+ * Restore $this from string representation.
+ *
+ * @param string $data The string representation
+ *
+ * @return void
+ *
+ * @internal
+ */
+ public function unserialize($data): void
+ {
+ /** @var mixed[] $dataArray */
+ $dataArray = unserialize($data);
+ $this->__unserialize($dataArray);
+ }
+
+ /**
+ * Prepend the list with an item.
+ *
+ * @param AllowedType $value The item to unshift
+ *
+ * @return void
+ *
+ * @throws InvalidDataTypeException if `$value` is not of allowed type
+ *
+ * @api
+ */
+ public function unshift(mixed $value): void
+ {
+ if (!$this->hasAllowedType($value)) {
+ throw new InvalidDataTypeException(
+ sprintf(
+ 'Parameter 1 must be an allowed type, %s given.',
+ get_debug_type($value)
+ )
+ );
+ }
+ parent::unshift($value);
+ }
+
+ /**
+ * Create a type-sensitive, traversable list of items.
+ *
+ * @param string[] $allowedTypes Allowed data types of items (optional)
+ *
+ * If empty, all types are allowed.
+ * Possible values are:
+ * - "array"
+ * - "bool"
+ * - "callable"
+ * - "countable"
+ * - "float" or "double"
+ * - "int" or "integer" or "long"
+ * - "iterable"
+ * - "null"
+ * - "numeric"
+ * - "object" or FQCN
+ * - "resource"
+ * - "scalar"
+ * - "string"
+ *
+ * @return void
+ *
+ * @throws InvalidArgumentException if any value of `$allowedTypes` is not a string
+ */
+ public function __construct(array $allowedTypes = [])
+ {
+ $this->setAllowedTypes($allowedTypes);
+ }
+
+ /**
+ * Get debug information for $this.
+ *
+ * @return mixed[] The debug information
+ *
+ * @internal
+ */
+ public function __debugInfo(): array
+ {
+ return $this->__serialize();
+ }
+
+ /**
+ * Get array representation of $this.
+ *
+ * @return mixed[] The array representation
+ *
+ * @internal
+ */
+ public function __serialize(): array
+ {
+ return [
+ 'StrictSplDatastructure::allowedTypes' => $this->getAllowedTypes(),
+ 'StrictSplDatastructure::dllist' => $this->toArray(),
+ 'StrictSplDatastructure::flags' => $this->getIteratorMode()
+ ];
+ }
+
+ /**
+ * Restore $this from array representation.
+ *
+ * @param mixed[] $data The array representation
+ *
+ * @return void
+ *
+ * @internal
+ *
+ * @psalm-suppress MethodSignatureMismatch
+ */
+ public function __unserialize(array $data): void
+ {
+ /** @var string[] $allowedTypes */
+ $allowedTypes = $data['StrictSplDatastructure::allowedTypes'];
+ $this->setAllowedTypes($allowedTypes);
+ /** @var array $values */
+ $values = $data['StrictSplDatastructure::dllist'];
+ $this->append(...$values);
+ /** @var int $flags */
+ $flags = $data['StrictSplDatastructure::flags'];
+ $this->setIteratorMode($flags);
+ }
+}