Program Listing for File CoreResource.hpp

Return to documentation for file (nvcv_types/include/nvcv/CoreResource.hpp)

/*
 * SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
 * SPDX-License-Identifier: Apache-2.0
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#ifndef NVCV_CORE_RESOURCE_HPP
#define NVCV_CORE_RESOURCE_HPP

#include "HandleWrapper.hpp"

namespace nvcv {

template<typename Handle, typename Actual>
class CoreResource : private SharedHandle<Handle>
{
public:
    using HandleType = Handle;
    using Base       = SharedHandle<Handle>;

    CoreResource() = default;

    CoreResource(std::nullptr_t) {}

    explicit CoreResource(HandleType &&handle)
        : Base(std::move(handle))
    {
    }

    static Actual FromHandle(HandleType handle, bool incRef)
    {
        if (incRef && handle)
            HandleIncRef(handle);
        return Actual(std::move(handle));
    }

    CoreResource(const Actual &other)
        : Base(other)
    {
    }

    CoreResource(Actual &&other)
        : Base(std::move(other))
    {
    }

    CoreResource &operator=(const Actual &other)
    {
        Base::operator=(other);
        return *this;
    }

    CoreResource &operator=(Actual &&other)
    {
        Base::operator=(std::move(other));
        return *this;
    }

    const HandleType handle() const noexcept
    {
        return this->get();
    }

    bool operator==(const Actual &other) const
    {
        return handle() == other.handle();
    }

    bool operator!=(const Actual &other) const
    {
        return handle() != other.handle();
    }

    using Base::empty;
    using Base::refCount;
    using Base::release;
    using Base::reset;
    using Base::operator bool;

    template<typename Derived>
    Derived cast() const
    {
        static_assert(std::is_base_of<Actual, Derived>::value, "Requested a cast to a type not derived from this one.");
        if (*this && Derived::IsCompatibleKind(This().type()))
        {
            return Derived::FromHandle(handle(), true);
        }
        else
        {
            return {};
        }
    }

protected:
    ~CoreResource() = default;

private:
    Actual &This()
    {
        return *static_cast<Actual *>(this);
    }

    const Actual &This() const
    {
        return *static_cast<const Actual *>(this);
    }
};

#define NVCV_IMPLEMENT_SHARED_RESOURCE(ClassName, BaseClassName) \
    using BaseClassName::BaseClassName;                          \
    using BaseClassName::operator=;                              \
    ClassName(const ClassName &other)                            \
        : BaseClassName(other)                                   \
    {                                                            \
    }                                                            \
    ClassName(ClassName &&other)                                 \
        : BaseClassName(std::move(other))                        \
    {                                                            \
    }                                                            \
    ClassName &operator=(const ClassName &other)                 \
    {                                                            \
        BaseClassName::operator=(other);                         \
        return *this;                                            \
    }                                                            \
    ClassName &operator=(ClassName &&other)                      \
    {                                                            \
        BaseClassName::operator=(std::move(other));              \
        return *this;                                            \
    }

template<typename Resource>
class NonOwningResource
{
public:
    using HandleType = typename Resource::HandleType;

    NonOwningResource(HandleType handle)
        : m_resource(std::move(handle))
    {
    }

    NonOwningResource(const NonOwningResource &) = delete;

    NonOwningResource(NonOwningResource &&) = default;

    NonOwningResource &operator=(const NonOwningResource &) = delete;

    NonOwningResource &operator=(NonOwningResource &&) = default;

    const HandleType handle() const
    {
        return m_resource.handle();
    }

    ~NonOwningResource()
    {
        (void)m_resource.release();
    }

    operator const Resource &() const &
    {
        return m_resource;
    }

private:
    Resource m_resource;
};

} // namespace nvcv

#endif // NVCV_CORE_RESOURCE_HPP