/* This file is part of Mapnik (c++ mapping toolkit) * Copyright (C) 2005 Artem Pavlenko * * Mapnik is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or any later version. * * 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, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ //$Id: utils.hpp 39 2005-04-10 20:39:53Z pavlenko $ #ifndef UTILS_HPP #define UTILS_HPP #include #include #include #include #include #include #include namespace mapnik { class Mutex; class Lock; template class CreateUsingNew { public: static T* create() { return new T; } static void destroy(T* obj) { delete obj; } }; template class CreateStatic { private: union MaxAlign { char t_[sizeof(T)]; short int shortInt_; int int_; long int longInt_; float float_; double double_; long double longDouble_; struct Test; int Test::* pMember_; int (Test::*pMemberFn_)(int); }; public: static T* create() { static MaxAlign staticMemory; return new(&staticMemory) T; } static void destroy(volatile T* obj) { obj->~T(); } }; template class CreatePolicy=CreateStatic> class singleton { friend class CreatePolicy; static T* pInstance_; static bool destroyed_; singleton(const singleton &rhs); singleton& operator=(const singleton&); static void onDeadReference() { throw std::runtime_error("dead reference!"); } protected: static Mutex mutex_; singleton() {} virtual ~singleton() { CreatePolicy::destroy(pInstance_); destroyed_=true; } public: static T* instance() { if (!pInstance_) { Lock lock(&mutex_); if (!pInstance_) { if (destroyed_) { onDeadReference(); } else { pInstance_=CreatePolicy::create(); } } } return pInstance_; } }; template class CreatePolicy> Mutex singleton::mutex_; template class CreatePolicy> T* singleton::pInstance_=0; template class CreatePolicy> bool singleton::destroyed_=false; template class Handle { T* ptr_; int* pCount_; public: T* operator->() {return ptr_;} const T* operator->() const {return ptr_;} Handle(T* ptr) :ptr_(ptr),pCount_(new int(1)) {} Handle(const Handle& rhs) :ptr_(rhs.ptr_),pCount_(rhs.pCount_) { (*pCount_)++; } Handle& operator=(const Handle& rhs) { if (ptr_==rhs.ptr_) return *this; if (--(*pCount_)==0) { delete ptr_; delete pCount_; } ptr_=rhs.ptr_; pCount_=rhs.pCount_; (*pCount_)++; return *this; } ~Handle() { if (--(*pCount_)==0) { delete ptr_; delete pCount_; } } }; class Mutex { private: pthread_mutex_t mutex_; public: Mutex() { pthread_mutex_init(&mutex_,0); } void lock() { pthread_mutex_lock(&mutex_); } void unlock() { pthread_mutex_unlock(&mutex_); } bool trylock() { return (pthread_mutex_trylock(&mutex_)==0); } ~Mutex() { pthread_mutex_destroy(&mutex_); } }; class Lock { private: Mutex* mutex_; public: explicit Lock(Mutex* mutex) :mutex_(mutex) { if (mutex_) mutex_->lock(); } ~Lock() { if (mutex_) mutex_->unlock(); } private: Lock(); Lock(const Lock&); Lock& operator=(const Lock&); void* operator new(std::size_t); void* operator new[](std::size_t); void operator delete(void*); void operator delete[](void*); Lock* operator&(); }; struct timer { struct timeval tv_; timer() { gettimeofday (&tv_,0); } void start() { gettimeofday (&tv_,0); } void stop() { timeval tv; gettimeofday (&tv,0); std::ostringstream s; long sec=1000*(tv.tv_sec-tv_.tv_sec); long total_ms=sec+static_cast(0.001*(tv.tv_usec-tv_.tv_usec)); s << "elapsed time is "< inline std::string toString(const T& x) { std::ostringstream o; if (!(o << x)) throw BadConversion(std::string("toString(") + typeid(x).name() + ")"); return o.str(); } template inline void fromString(const std::string& s, T& x, bool failIfLeftoverChars = true) { std::istringstream i(s); char c; if (!(i >> x) || (failIfLeftoverChars && i.get(c))) throw BadConversion("fromString("+s+")"); } inline bool space (char c) { return isspace(c); } inline bool not_space (char c) { return !isspace(c); } inline std::string trim_left(const std::string& str) { typedef std::string::const_iterator iter; iter i = find_if(str.begin(),str.end(),not_space); return std::string(i,str.end()); } inline std::string trim_right(const std::string& str) { std::string::size_type idx=str.find_last_not_of(" "); return str.substr(0,idx+1); } inline std::string trim(const std::string& str) { return trim_left(trim_right(str)); } } #endif //UTILS_HPP