// Copyright (c) 2005-2009 Hartmut Kaiser // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) #ifndef SAGA_IMPL_ENGINE_UUID_HPP #define SAGA_IMPL_ENGINE_UUID_HPP #include #include #include #include #include #include #include /////////////////////////////////////////////////////////////////////////////// namespace saga { namespace impl { /////////////////////////////////////////////////////////////////////////////// class uuid { private: mutable unsigned long int uuid_; /////////////////////////////////////////////////////////////////////////////// static int & cnt_instance (void) { static int cnt; cnt++; // FIXME: should print a warning here if ( cnt == ULONG_MAX ) { // avoid zero cnt = 1; } return cnt; } static void cnt_init (void) { int cnt = cnt_instance (); cnt = 0; } static void initialize_cnt (void) { static boost::once_flag been_here_cnt = BOOST_ONCE_INIT; boost::call_once (cnt_init, been_here_cnt); } /////////////////////////////////////////////////////////////////////////////// static boost::mutex & mutex_instance (void) { static boost::mutex mutex; return mutex; } static void mutex_init (void) { mutex_instance (); } static void initialize_mutex (void) { static boost::once_flag been_here_mtx = BOOST_ONCE_INIT; boost::call_once (mutex_init, been_here_mtx); } /////////////////////////////////////////////////////////////////////////////// static void from_string (int & id, std::string const & str) { id = boost::lexical_cast (str); // if ( sscanf (str, "%lu", id) != 1 ) // { // // nothing found - revert to fallback zero // // This will cause an exception in ensure_is_initialized // id = 0; // } } static bool is_null (int const & id) { return ( id == 0 ); } /////////////////////////////////////////////////////////////////////////////// public: uuid (void) : uuid_ (0) { } uuid (char const * uuid_str) { create (uuid_str); } void ensure_is_initialized (void) const { if ( is_null (uuid_) ) { create (); } if ( is_null (uuid_) ) { SAGA_THROW_NO_OBJECT ("Could not create UUID for this object", saga::NoSuccess); } } std::string string (void) const { ensure_is_initialized (); return boost::lexical_cast (uuid_); } // create new uuid from scratch void create (void) const { initialize_mutex (); boost::mutex::scoped_lock lock (mutex_instance ()); initialize_cnt (); uuid_ = cnt_instance (); } // create new uuid from string void create (char const * str) const { initialize_mutex (); boost::mutex::scoped_lock lock (mutex_instance ()); from_string (uuid_, str); } // comparison operators friend bool operator== (uuid const & lhs, uuid const & rhs) { lhs.ensure_is_initialized(); rhs.ensure_is_initialized(); return lhs.uuid_ == rhs.uuid_; } friend bool operator!= (uuid const & lhs, uuid const & rhs) { return !(lhs == rhs); } friend bool operator< (uuid const & lhs, uuid const & rhs) { lhs.ensure_is_initialized(); rhs.ensure_is_initialized(); return lhs.uuid_ < rhs.uuid_; } friend bool operator> (uuid const & lhs, uuid const & rhs) { lhs.ensure_is_initialized(); rhs.ensure_is_initialized(); return lhs.uuid_ > rhs.uuid_; } friend bool operator<= (uuid const & lhs, uuid const & rhs) { return !(lhs > rhs); } friend bool operator>= (uuid const & lhs, uuid const & rhs) { return !(lhs < rhs); } }; uuid const null_uuid = uuid (); /////////////////////////////////////////////////////////////////////////////// } } // namespace saga::impl #endif // SAGA_SAGA_ENGINE_UUID_UUID_HPP