AUI Framework  develop
Cross-platform base for C++ UI apps
Loading...
Searching...
No Matches
APimpl.h
    1/*
    2 * AUI Framework - Declarative UI toolkit for modern C++20
    3 * Copyright (C) 2020-2025 Alex2772 and Contributors
    4 *
    5 * SPDX-License-Identifier: MPL-2.0
    6 *
    7 * This Source Code Form is subject to the terms of the Mozilla Public
    8 * License, v. 2.0. If a copy of the MPL was not distributed with this
    9 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
   10 */
   11
   12#pragma once
   13
   14#include <cstdint>
   15#include <AUI/Traits/types.h>
   16
   17
   18namespace aui {
   30    template<typename T, std::size_t storageSize, std::size_t storageAlignment = 8>
   31    struct fast_pimpl {
   32    public:
   33        template<typename... Args>
   34        fast_pimpl(Args&&... args) {
   35            new (ptr()) T(std::forward<Args>(args)...);
   36            static_assert(storageSize >= sizeof(T), "not enough size");
   37            static_assert(storageAlignment % alignof(T) == 0, "alignment does not match");
   38        }
   39
   40        fast_pimpl(const fast_pimpl& other) {
   41            new (ptr()) T(other.value());
   42        }
   43
   44        fast_pimpl(fast_pimpl&& other) noexcept {
   45            new (ptr()) T(std::move(other.value()));
   46        }
   47
   48        fast_pimpl& operator=(const fast_pimpl& other) {
   49            new (ptr()) T(other.value());
   50            return *this;
   51        }
   52
   53        fast_pimpl& operator=(fast_pimpl&& other) noexcept {
   54            new (ptr()) T(std::move(other.value()));
   55            return *this;
   56        }
   57
   58        fast_pimpl& operator=(T&& other) noexcept {
   59            new (ptr()) T(std::move(other));
   60            return *this;
   61        }
   62
   63
   64        ~fast_pimpl() {
   65            ptr()->~T();
   66        }
   67
   68        [[nodiscard]]
   69        T& value() noexcept {
   70            return reinterpret_cast<T&>(mStorage);
   71        }
   72
   73        [[nodiscard]]
   74        const T& value() const noexcept {
   75            return reinterpret_cast<const T&>(mStorage);
   76        }
   77
   78        [[nodiscard]]
   79        T* ptr() noexcept {
   80            return &reinterpret_cast<T&>(mStorage);
   81        }
   82
   83        [[nodiscard]]
   84        const T* ptr() const noexcept {
   85            return &reinterpret_cast<const T&>(mStorage);
   86        }
   87
   88        [[nodiscard]]
   89        T* operator->() noexcept {
   90            return &reinterpret_cast<T&>(mStorage);
   91        }
   92
   93        [[nodiscard]]
   94        const T* operator->() const noexcept {
   95            return &reinterpret_cast<const T&>(mStorage);
   96        }
   97
   98        [[nodiscard]]
   99        T& operator*() noexcept {
  100            return reinterpret_cast<T&>(mStorage);
  101        }
  102
  103        [[nodiscard]]
  104        const T& operator*() const noexcept {
  105            return reinterpret_cast<const T&>(mStorage);
  106        }
  107
  108
  109    private:
  110        std::aligned_storage_t<storageSize, storageAlignment> mStorage;
  111    };
  112}
API_AUI_CORE const ACommandLineArgs & args() noexcept