// Matrix Construct // // Copyright (C) Matrix Construct Developers, Authors & Contributors // Copyright (C) 2016-2018 Jason Volk // // Permission to use, copy, modify, and/or distribute this software for any // purpose with or without fee is hereby granted, provided that the above // copyright notice and this permission notice is present in all copies. The // full license for this software is available in the LICENSE file. #pragma once #define HAVE_IRCD_M_IMPORT_H namespace ircd::m { template struct import; struct imports extern imports; } struct ircd::m::imports :std::map> { void init(); }; template struct ircd::m::import :mods::import { std::string modname; std::string symname; void reload(); public: template auto operator()(args&&... a); prototype *operator->(); prototype &operator*(); operator prototype &(); import(std::string modname, std::string symname); }; template ircd::m::import::import(std::string modname, std::string symname) :mods::import{} ,modname{std::move(modname)} ,symname{std::move(symname)} {} template ircd::m::import::operator prototype &() { return this->operator*(); } template prototype & ircd::m::import::operator*() { return *this->operator->(); } template prototype * ircd::m::import::operator->() { if(unlikely(!*this)) reload(); return mods::import::operator->(); } template template auto ircd::m::import::operator()(args&&... a) { if(unlikely(!*this)) reload(); return mods::import::operator()(std::forward(a)...); } template void ircd::m::import::reload() try { auto &import(static_cast &>(*this)); import = { imports.at(modname), symname }; } catch(const std::out_of_range &e) { throw m::UNAVAILABLE { "Sorry, %s in %s is currently unavailable.", symname, modname }; }