blob: b7f4acc77ab12400a6dc0d9375dcecc3660f9c2c [file] [edit]
/*
* Copyright © 2020 Canonical Ltd.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 3,
* as published by the Free Software Foundation.
*
* 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 <http://www.gnu.org/licenses/>.
*
* Authored by: Christopher James Halse Rogers <christopher.halse.rogers@canonical.com>
* William Wold <william.wold@canonical.com>
*/
#ifndef WLCS_WL_PROXY_H_
#define WLCS_WL_PROXY_H_
#include "wl_interface_descriptor.h"
#include "boost/throw_exception.hpp"
#include "boost/current_function.hpp"
#include <string>
#include <stdexcept>
struct wl_proxy;
namespace wlcs
{
template<typename T>
class WlHandle
{
public:
explicit WlHandle(T* const proxy)
: proxy{proxy},
owns_wl_object{true}
{
static_assert(
WlInterfaceDescriptor<T>::has_specialisation,
"Missing specialisation for WlInterfaceDescriptor");
if (proxy == nullptr)
{
BOOST_THROW_EXCEPTION((std::logic_error{"Attempt to construct a WlHandle from null Wayland object"}));
}
}
~WlHandle()
{
if (owns_wl_object)
{
(*WlInterfaceDescriptor<T>::destructor)(proxy);
}
}
WlHandle(WlHandle&& from)
: WlHandle(from.proxy)
{
from.owns_wl_object = false;
}
WlHandle(WlHandle const&) = delete;
auto operator=(WlHandle&&) -> WlHandle& = delete;
auto operator=(WlHandle const&) -> bool = delete;
operator T*() const
{
// This is a precondition failure, but as this is a test-suite let's be generous and make it fail hard and fast
if (!owns_wl_object)
{
std::abort();
}
return proxy;
}
auto wl_proxy() const -> struct wl_proxy*
{
// This is a precondition failure, but as this is a test-suite let's be generous and make it fail hard and fast
if (!owns_wl_object)
{
std::abort();
}
return static_cast<struct wl_proxy*>(proxy);
}
private:
T* const proxy;
bool owns_wl_object;
};
template<typename WlType>
auto wrap_wl_object(WlType* proxy) -> WlHandle<WlType>
{
return WlHandle<WlType>{proxy};
}
}
#endif // WLCS_WL_PROXY_H_