<?php
/**
 * Reusable singleton behaviour.
 *
 * @package Donatico\Traits
 */

declare(strict_types=1);

namespace Donatico\Traits;

/**
 * Provides getInstance(), and seals clone/unserialize to enforce
 * the singleton contract on any class that uses this trait.
 */
trait SingletonTrait {

	/** @var static|null */
	private static ?self $instance = null;

	/**
	 * Return the single shared instance of the class.
	 *
	 * @return static
	 */
	public static function getInstance(): static {
		if ( null === static::$instance ) {
			static::$instance = new static();
		}
		return static::$instance;
	}

	/** @return void */
	private function __construct() {}

	/** @return void */
	public function __clone() {}

	/**
	 * @return void
	 * @throws \Exception Always — singletons must not be unserialized.
	 */
	public function __wakeup(): void {
		throw new \Exception( 'Singletons cannot be unserialized.' );
	}
}
