<commit_before>/*!
** \file Singleton.h
** \author <NAME> <<EMAIL>>
** \date Thu Oct 14 2004
** Copyright (C) 2004 by <NAME>
**
** 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
** 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, you may access it via the web
** at http://www.gnu.org/copyleft/lesser.html .
*/

#ifndef FINAGLE_SINGLETON_H
#define FINAGLE_SINGLETON_H

#include <Finagle/Mutex.h>
#include <Finagle/ObjectPtr.h>

namespace Finagle {

/*!
** \brief Template for create-on-first-use singletons
**
** Creates an instance of the object on first use (except when the copy constructor is used).  Destroy when last the last code unit
** (i.e. source file that includes the executable) has been unloaded.
**
** * Usage
** - Add the Singleton as a static object in your header file(s), e.g.:
**   static Singleton<ThingClass> theThing;
** - Access via function operator, e.g.:
**    theThing().doStuff();
*/
template <typename Type, typename TypePtr = Type *>
class Singleton {
public:
  Singleton( void );
  Singleton( Type const &init );
 ~Singleton( void );

  Type &operator ()( void );
  Type &operator ()( Type *that );

private:
  Type &alloc( void );
  Type &alloc( Type const &init );

private:
  static unsigned _useCount;
  static TypePtr _inst;
};

// INLINE/TEMPLATE IMPLEMENTATION *********************************************

template <typename Type, typename TypePtr>
unsigned Singleton<Type, TypePtr>::_useCount = 0;

template <typename Type, typename TypePtr>
TypePtr Singleton<Type, TypePtr>::_inst = 0;


template <typename Type, typename TypePtr>
inline Singleton<Type, TypePtr>::Singleton( void )
{
  _useCount++;
}

template <typename Type, typename TypePtr>
inline Singleton<Type, TypePtr>::Singleton( Type const &that )
{
  _useCount++;
  _inst = new Type(that);
}

template <typename Type, typename TypePtr>
inline Singleton<Type, TypePtr>::~Singleton( void )
{
  if ( _inst && !--_useCount ) {
    delete _inst;
    _inst = 0;
  }
}

template <typename Type, typename TypePtr>
inline Type &Singleton<Type, TypePtr>::operator ()( void )
{
  return _inst ? *_inst : alloc();
}

template <typename Type, typename TypePtr>
inline Type &Singleton<Type, TypePtr>::operator ()( Type *that )
{
  delete _inst;
  _inst = that;
  return *_inst;
}


template <typename Type, typename TypePtr>
Type &Singleton<Type, TypePtr>::alloc( void )
{
  static Finagle::Mutex guard;
  Finagle::Lock lock( guard );

  if ( !_inst )
    _inst = new Type;

  return *_inst;
}

};

#endif
<commit_msg>Singleton: refactored, expand thread-safety.<commit_after>/*!
** \file Singleton.h
** \author <NAME> <<EMAIL>>
** \date Thu Oct 14 2004
** Copyright (C) 2004 by <NAME>
**
** 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
** 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, you may access it via the web
** at http://www.gnu.org/copyleft/lesser.html .
*/

#ifndef FINAGLE_SINGLETON_H
#define FINAGLE_SINGLETON_H

#include <Finagle/Mutex.h>
#include <Finagle/ObjectPtr.h>

namespace Finagle {

/*!
** \brief Template for create-on-first-use singletons
**
** Creates an instance of the object on first use (except when the copy constructor is used).  Destroy when last the last code unit
** (i.e. source file that includes the executable) has been unloaded.
**
** * Usage
** - Add the Singleton as a static object in your header file(s), e.g.:
**   static Singleton<ThingClass> theThing;
** - Access via function operator, e.g.:
**    theThing().doStuff();
*/
template <typename Type, typename TypePtr = Type *>
class Singleton {
public:
  Singleton( void );
 ~Singleton( void );

  Type &operator ()( void );
  Type &operator ()( Type *that );

private:
  Type &alloc( void );
  void  free( void );

private:
  static Finagle::Mutex _guard;
  static unsigned _useCount;
  static TypePtr _inst;
};

// INLINE/TEMPLATE IMPLEMENTATION *********************************************

template <typename Type, typename TypePtr>
unsigned Singleton<Type, TypePtr>::_useCount = 0;

template <typename Type, typename TypePtr>
Finagle::Mutex Singleton<Type, TypePtr>::_guard;

template <typename Type, typename TypePtr>
TypePtr Singleton<Type, TypePtr>::_inst = 0;


template <typename Type, typename TypePtr>
inline Singleton<Type, TypePtr>::Singleton( void )
{
  _useCount++;
}

template <typename Type, typename TypePtr>
inline Singleton<Type, TypePtr>::~Singleton( void )
{
  if ( _inst && !--_useCount )
    free();
}

template <typename Type, typename TypePtr>
inline Type &Singleton<Type, TypePtr>::operator ()( void )
{
  Finagle::Lock lock( _guard );
  return _inst ? *_inst : alloc();
}

template <typename Type, typename TypePtr>
inline Type &Singleton<Type, TypePtr>::operator ()( Type *that )
{
  if ( that != _inst ) {
    Finagle::Lock lock( _guard );
    free();
    _inst = that;
  }
  return *_inst;
}


template <typename Type, typename TypePtr>
Type &Singleton<Type, TypePtr>::alloc( void )
{
  if ( !_inst )
    _inst = new Type;
  return *_inst;
}

template <typename Type, typename TypePtr>
void Singleton<Type, TypePtr>::free( void )
{
  delete _inst;
  _inst = 0;
}

};

#endif

{'fraction_non_alphanumeric': 0.13232667640850787, 'fraction_numerical': 0.004870920603994155, 'mean_word_length': 4.365853658536586, 'pattern_counts': {'":': 0, '<': 53, '<?xml version=': 0, '>': 53, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4967629', 'n_tokens_mistral': 1924, 'n_tokens_neox': 1854, 'n_words': 705}