OEOnce¶
template<class T>
struct OEOnce
OEOnce is deprecated. OpenEye strongly recommends using one of the alternatives below instead of `OEOnce`
OEOnce was created to facilitate thread-safe initialization of function-local-statics before C++11’s magic-statics were universally available. Its implementation has become redundant since moving to VS2015 with full C++11 compliance. All of the existing uses will continue to work as intended without change, with minimal overhead in compile and run time for optimized release builds, in most cases.
Alternatives
Function local static instances:
Only use when required - there is a performance cost!
Make const unless you can’t.
Fully construct static local in a single line:
Via constructor:
static const SomeClass someInstance{"abc", 1.23f, 456};
Via function result:
static const int tag = OEGetTag(”my_tag”);
Use
std::unique_ptr
when you must have a pointer, or for very large objects:static const std::unique_ptr<Class2> up{factoryFunc()};
When call-once is truly desired:
std::atomic_flag
Define at file scope if you can
init with
= ATOMIC_FLAG_INIT;
Use
std::atomic_flag::test_and_set
in conditional
std::once_flag/call_once
Define
std::once_flag
at file scope if you canProvides exception handling
Can handle more complex situations
Original Documentation
This class is used to do thread-safe one time initialization of an
object as a function local static. It is intended to imitate the
behavior of the C++11 “magic statics” feature. The default
constructor of the class T
is guaranteed to be called once, and
only once, and all other threads will block until initialization is
complete.
The following code snippet demonstrates how to use OEOnce
to
cache an initialized OESubSearch object to be used
by subsequent function invocations:
class PhenylSubSearch
{
OESubSearch _subsrch;
public:
PhenylSubSearch() : _subsrch("c1ccccc1") { }
const OESubSearch &GetSubSearch() const { return _subsrch; }
};
bool HasPhenyl(const OEMolBase &mol)
{
static OEOnce<PhenylSubSearch> phenylSubSrch = OE_ONCE_INIT;
return phenylSubSrch->GetSubSearch().SingleMatch(mol);
}
Warning
The thread safety of the object T
is the responsibility of the
user. OEOnce
will only ensure that there is only one of them
initialized for the whole lifetime of the process and that its
destructor is called during process exit.
operator*¶
T &operator*()
Dereference that OEOnce
object, returning a reference to the
singleton T
object. The reference will only be returned once
at least one thread has fully initialized the object.
operator->¶
T *operator->()
Allows the OEOnce
object to behave like a pointer to
T
. The pointer will only be returned once at least one
thread has fully initialized the object.
operator T *¶
operator T *()
Allows the OEOnce
object to be cast to a pointer of
T
. The pointer will only be returned once at least one
thread has fully initialized the object.
GetValue¶
T *GetValue()
Returns the pointer to a singleton object initialized in a thread safe way. The pointer will only be returned once at least one thread has fully initialized the object.