LoginSignup
4
4

More than 5 years have passed since last update.

初期化遅延クラス

Posted at

ほぼoptional。templateの練習して

#pragma once
#include <type_traits>
#include <assert.h>

template<typename T>
class LazyInit_Base{
public:
    LazyInit_Base() : constructed_(false) {}
    ~LazyInit_Base() {
        if(!isConstructed()) return;
        static_cast<T*>((void*)(&seat_))->~T();
        constructed_ = false;
    }

    T * operator->() const{
        return static_cast<T*>((void*)(&seat_));
    }

    T & operator*() const{
        return *static_cast<T*>((void*)(&seat_));
    }

    template<typename ...Args>
    void construct(Args... args) {
        assert(constructed_ == false);
        new(&seat_) T(std::forward<Args>(args)...);
        constructed_ = true;
    }

    bool isConstructed() const{
        return constructed_;
    }

    explicit operator bool() const{
        return isConstructed();
    }
private:
    bool constructed_;
    typename std::aligned_storage<sizeof(T), std::alignment_of<T>::value>::type seat_;
};

template<
    typename T,
    bool IsCopyable = std::is_copy_assignable<typename std::remove_const<T>::type>::value && std::is_copy_constructible<typename std::remove_const<T>::type>::value
>
class LazyInit : public LazyInit_Base<T>{
public:
    LazyInit() = default;
    LazyInit(const LazyInit & rhs) {
        construct(*rhs);
    }
    LazyInit & operator=(const LazyInit&) = delete;

    template <typename U>
    LazyInit(const LazyInit<U> & rhs) {
        static_assert(std::is_convertible<U, T>::value == true, "U not convertible to T");
        construct(*rhs);
    }
};

template<typename T>
class LazyInit<T, false> : public LazyInit_Base<T>{
public:
    LazyInit() = default;
    LazyInit(const LazyInit&) = delete;
    LazyInit(LazyInit &&) = delete;
    LazyInit & operator=(const LazyInit&) = delete;
};
4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4