/* * Copyright (C) 2016 Charybdis Development Team * Copyright (C) 2016 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. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #pragma once #define HAVE_IRCD_JS_ID_H namespace ircd { namespace js { namespace basic { template struct id :root { operator value() const; using root::root; explicit id(const char *const &); // creates new id explicit id(const std::string &); // creates new id id(const typename string::handle &); id(const typename value::handle &); id(const value &); id(const string &); id(const JSProtoKey &); id(const uint32_t &); id(const jsid &); id(); }; } // namespace basic using id = basic::id; using heap_id = basic::id; bool operator==(const handle &, const char *const &); bool operator==(const handle &, const std::string &); bool operator==(const char *const &, const handle &); bool operator==(const std::string &, const handle &); // // Implementation // namespace basic { template id::id() :id::root::type{} { } template id::id(const jsid &i) :id::root::type{i} { } template id::id(const uint32_t &index) :id::root::type{} { if(!JS_IndexToId(*cx, index, &(*this))) throw type_error("Failed to construct id from uint32_t index"); } template id::id(const JSProtoKey &key) :id::root::type{} { JS::ProtoKeyToId(*cx, key, &(*this)); } template id::id(const std::string &str) :id(str.c_str()) { } template id::id(const char *const &str) :id::root::type{jsid()} { if(!JS::PropertySpecNameToPermanentId(*cx, str, this->address())) throw type_error("Failed to create id from native string"); } template id::id(const string &h) :id::id(typename string::handle(h)) { } template id::id(const value &h) :id::id(typename value::handle(h)) { } template id::id(const typename value::handle &h) :id::root::type{} { if(!JS_ValueToId(*cx, h, &(*this))) throw type_error("Failed to construct id from Value"); } template id::id(const typename string::handle &h) :id::root::type{} { if(!JS_StringToId(*cx, h, &(*this))) throw type_error("Failed to construct id from String"); } template id::operator value() const { value ret; if(!JS_IdToValue(*cx, *this, &ret)) throw type_error("Failed to construct id from String"); return ret; } } // namespace basic inline bool operator==(const std::string &a, const handle &b) { return operator==(a.c_str(), b); } inline bool operator==(const char *const &a, const handle &b) { return JS::PropertySpecNameEqualsId(a, b); } inline bool operator==(const handle &a, const std::string &b) { return operator==(a, b.c_str()); } inline bool operator==(const handle &a, const char *const &b) { return JS::PropertySpecNameEqualsId(b, a); } } // namespace js } // namespace ircd