mapnik/include/mapnik/utils.hpp

171 lines
4.1 KiB
C++
Raw Normal View History

2006-11-29 00:14:25 +00:00
/*****************************************************************************
2012-02-02 01:53:35 +00:00
*
2006-11-29 00:14:25 +00:00
* This file is part of Mapnik (c++ mapping toolkit)
*
2014-11-20 14:25:50 +00:00
* Copyright (C) 2014 Artem Pavlenko
*
2006-11-29 00:14:25 +00:00
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
2006-11-29 00:14:25 +00:00
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
2006-11-29 00:14:25 +00:00
*****************************************************************************/
#ifndef MAPNIK_UTILS_HPP
#define MAPNIK_UTILS_HPP
2008-02-04 16:12:13 +00:00
#include <mapnik/config.hpp>
2014-07-23 02:36:39 +00:00
#include <mapnik/unique_lock.hpp>
// stl
2014-07-23 05:40:39 +00:00
#include <stdexcept> // std::runtime_error
#include <cstdlib> // std::atexit
#include <new> // operator new
2008-02-04 16:12:13 +00:00
#ifdef MAPNIK_THREADSAFE
#include <mutex>
2008-02-04 16:12:13 +00:00
#endif
2012-02-02 01:53:35 +00:00
namespace mapnik
{
2010-06-02 11:03:30 +00:00
template <typename T>
class CreateUsingNew
{
public:
static T* create()
{
2010-06-02 11:03:30 +00:00
return new T;
}
static void destroy(T* obj)
{
delete obj;
}
};
2010-06-02 11:03:30 +00:00
template <typename T>
class CreateStatic
{
private:
union MaxAlign
{
2010-06-02 11:03:30 +00:00
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);
};
2010-06-02 11:03:30 +00:00
public:
2012-02-02 01:53:35 +00:00
2010-06-02 11:03:30 +00:00
static T* create()
{
static MaxAlign staticMemory;
return new(&staticMemory) T;
}
static void destroy(volatile T* obj)
2010-06-02 11:03:30 +00:00
{
obj->~T();
}
};
2012-02-02 01:53:35 +00:00
#ifdef __GNUC__
2010-06-02 11:03:30 +00:00
template <typename T,
template <typename U> class CreatePolicy=CreateStatic> class MAPNIK_DECL singleton
2010-06-02 11:03:30 +00:00
{
#else
template <typename T,
template <typename U> class CreatePolicy=CreateStatic> class singleton
{
#endif
friend class CreatePolicy<T>;
static T* pInstance_;
static bool destroyed_;
singleton(const singleton &rhs);
singleton& operator=(const singleton&);
static void onDeadReference()
{
throw std::runtime_error("dead reference!");
}
2012-04-08 00:20:56 +00:00
static void DestroySingleton()
{
CreatePolicy<T>::destroy(pInstance_);
pInstance_ = 0;
destroyed_ = true;
}
2012-02-02 01:53:35 +00:00
protected:
2012-02-02 01:53:35 +00:00
2008-02-04 16:12:13 +00:00
#ifdef MAPNIK_THREADSAFE
static std::mutex mutex_;
2008-02-04 16:12:13 +00:00
#endif
2013-05-20 11:05:22 +00:00
singleton() {}
public:
static T& instance()
2010-06-02 11:03:30 +00:00
{
2012-04-08 00:20:56 +00:00
if (! pInstance_)
2010-06-02 11:03:30 +00:00
{
2013-05-20 11:05:22 +00:00
#ifdef MAPNIK_THREADSAFE
mapnik::scoped_lock lock(mutex_);
2013-05-20 11:05:22 +00:00
#endif
if (! pInstance_)
2010-06-02 11:03:30 +00:00
{
2013-05-20 11:05:22 +00:00
if (destroyed_)
{
destroyed_ = false;
onDeadReference();
}
else
{
pInstance_ = CreatePolicy<T>::create();
// register destruction
std::atexit(&DestroySingleton);
}
2010-06-02 11:03:30 +00:00
}
}
2013-05-20 11:05:22 +00:00
return *pInstance_;
2010-06-02 11:03:30 +00:00
}
};
2008-02-04 16:12:13 +00:00
#ifdef MAPNIK_THREADSAFE
2013-05-20 11:05:22 +00:00
template <typename T,
template <typename U> class CreatePolicy> std::mutex singleton<T,CreatePolicy>::mutex_;
2008-02-04 16:12:13 +00:00
#endif
2012-02-02 01:53:35 +00:00
2013-05-20 11:05:22 +00:00
template <typename T,
template <typename U> class CreatePolicy> T* singleton<T,CreatePolicy>::pInstance_=0;
template <typename T,
template <typename U> class CreatePolicy> bool singleton<T,CreatePolicy>::destroyed_=false;
#ifdef _WINDOWS
// UTF8 <--> UTF16 conversion routines
2013-05-20 11:05:22 +00:00
MAPNIK_DECL std::string utf16_to_utf8(std::wstring const& wstr);
MAPNIK_DECL std::wstring utf8_to_utf16(std::string const& str);
2013-05-20 11:05:22 +00:00
#endif // _WINDOWS
}
#endif // MAPNIK_UTILS_HPP