// // Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo // // The contents of this file are covered under the licence agreement in the // file "LICENCE" distributed with Cforall. // // InternedString.h -- // // Author : Aaron B. Moss // Created On : Thu Jun 14 11:15:00 2018 // Last Modified By : Aaron B. Moss // Last Modified On : Thu Jun 14 11:15:00 2018 // Update Count : 1 // #pragma once #include #include #include #include /// Keeps canonical copies of a std::string for quicker comparisons class interned_string { /// Shared map of canonical string representations static std::unordered_set< std::string > canonical; /// Canonical representation of empty string static const std::string* empty_string() { static const std::string* mt = [](){ return &*canonical.emplace( "" ).first; }(); return mt; } /// Canonicalize string template static const std::string* intern( S&& s ) { return &*canonical.emplace( std::forward(s) ).first; } /// Pointer to stored string const std::string* s; public: interned_string() : s{empty_string()} {} interned_string(const char* cs) : s{intern(cs)} {} interned_string(const std::string& ss) : s{intern(ss)} {} /// Invalid string interned_string(std::nullptr_t) : s{nullptr} {} operator const std::string& () const { return *s; } const std::string& str() const { return (const std::string&)*this; } bool operator== (const interned_string& o) const { return s == o.s; } bool operator!= (const interned_string& o) const { return s != o.s; } /// Check for invalid string explicit operator bool () { return s != nullptr; } }; inline std::ostream& operator<< (std::ostream& out, const interned_string& s) { return out << (const std::string&)s; } namespace std { template<> struct hash { std::size_t operator() (const interned_string& s) const { return std::hash{}( &(const std::string&)s ); } }; } // Local Variables: // // tab-width: 4 // // mode: c++ // // compile-command: "make install" // // End: //