mirror of
https://github.com/boostorg/utility.git
synced 2025-05-09 15:04:00 +00:00
Added boost::initialized<T> as was agreed at http://lists.boost.org/Archives/boost/2010/04/164916.php -- see #3472
[SVN r61883]
This commit is contained in:
parent
e3c982287a
commit
22743ee125
@ -9,6 +9,7 @@
|
|||||||
// 23 May 2008 (Fixed operator= const issue, added initialized_value) Niels Dekker, Fernando Cacciola
|
// 23 May 2008 (Fixed operator= const issue, added initialized_value) Niels Dekker, Fernando Cacciola
|
||||||
// 21 Ago 2008 (Added swap) Niels Dekker, Fernando Cacciola
|
// 21 Ago 2008 (Added swap) Niels Dekker, Fernando Cacciola
|
||||||
// 20 Feb 2009 (Fixed logical const-ness issues) Niels Dekker, Fernando Cacciola
|
// 20 Feb 2009 (Fixed logical const-ness issues) Niels Dekker, Fernando Cacciola
|
||||||
|
// 03 Apr 2010 (Added initialized<T>, suggested by Jeffrey Hellrung, fixing #3472) Niels Dekker
|
||||||
//
|
//
|
||||||
#ifndef BOOST_UTILITY_VALUE_INIT_21AGO2002_HPP
|
#ifndef BOOST_UTILITY_VALUE_INIT_21AGO2002_HPP
|
||||||
#define BOOST_UTILITY_VALUE_INIT_21AGO2002_HPP
|
#define BOOST_UTILITY_VALUE_INIT_21AGO2002_HPP
|
||||||
@ -28,10 +29,19 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <new>
|
#include <new>
|
||||||
|
|
||||||
|
#ifdef BOOST_MSVC
|
||||||
|
#pragma warning(push)
|
||||||
|
#if _MSC_VER >= 1310
|
||||||
|
// It is safe to ignore the following warning from MSVC 7.1 or higher:
|
||||||
|
// "warning C4351: new behavior: elements of array will be default initialized"
|
||||||
|
#pragma warning(disable: 4351)
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace boost {
|
namespace boost {
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
class value_initialized
|
class initialized
|
||||||
{
|
{
|
||||||
private :
|
private :
|
||||||
struct wrapper
|
struct wrapper
|
||||||
@ -40,6 +50,18 @@ class value_initialized
|
|||||||
typename
|
typename
|
||||||
#endif
|
#endif
|
||||||
remove_const<T>::type data;
|
remove_const<T>::type data;
|
||||||
|
|
||||||
|
wrapper()
|
||||||
|
:
|
||||||
|
data()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
wrapper(T const & arg)
|
||||||
|
:
|
||||||
|
data(arg)
|
||||||
|
{
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
mutable
|
mutable
|
||||||
@ -55,30 +77,26 @@ class value_initialized
|
|||||||
|
|
||||||
public :
|
public :
|
||||||
|
|
||||||
value_initialized()
|
initialized()
|
||||||
{
|
{
|
||||||
|
// Note: the following memset call will become conditional when ticket #3869 is fixed:
|
||||||
|
// https://svn.boost.org/trac/boost/ticket/3869 reported by Aleksey Gurtovoy.
|
||||||
std::memset(&x, 0, sizeof(x));
|
std::memset(&x, 0, sizeof(x));
|
||||||
#ifdef BOOST_MSVC
|
|
||||||
#pragma warning(push)
|
|
||||||
#if _MSC_VER >= 1310
|
|
||||||
// When using MSVC 7.1 or higher, the following placement new expression may trigger warning C4345:
|
|
||||||
// "behavior change: an object of POD type constructed with an initializer of the form ()
|
|
||||||
// will be default-initialized". It is safe to ignore this warning when using value_initialized.
|
|
||||||
#pragma warning(disable: 4345)
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
new (wrapper_address()) wrapper();
|
new (wrapper_address()) wrapper();
|
||||||
#ifdef BOOST_MSVC
|
|
||||||
#pragma warning(pop)
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
value_initialized(value_initialized const & arg)
|
initialized(initialized const & arg)
|
||||||
{
|
{
|
||||||
new (wrapper_address()) wrapper( static_cast<wrapper const &>(*(arg.wrapper_address())));
|
new (wrapper_address()) wrapper( static_cast<wrapper const &>(*(arg.wrapper_address())));
|
||||||
}
|
}
|
||||||
|
|
||||||
value_initialized & operator=(value_initialized const & arg)
|
explicit initialized(T const & arg)
|
||||||
|
{
|
||||||
|
new (wrapper_address()) wrapper(arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
initialized & operator=(initialized const & arg)
|
||||||
{
|
{
|
||||||
// Assignment is only allowed when T is non-const.
|
// Assignment is only allowed when T is non-const.
|
||||||
BOOST_STATIC_ASSERT( ! is_const<T>::value );
|
BOOST_STATIC_ASSERT( ! is_const<T>::value );
|
||||||
@ -86,7 +104,7 @@ class value_initialized
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
~value_initialized()
|
~initialized()
|
||||||
{
|
{
|
||||||
wrapper_address()->wrapper::~wrapper();
|
wrapper_address()->wrapper::~wrapper();
|
||||||
}
|
}
|
||||||
@ -101,17 +119,76 @@ class value_initialized
|
|||||||
return wrapper_address()->data;
|
return wrapper_address()->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
void swap(value_initialized & arg)
|
void swap(initialized & arg)
|
||||||
{
|
{
|
||||||
::boost::swap( this->data(), arg.data() );
|
::boost::swap( this->data(), arg.data() );
|
||||||
}
|
}
|
||||||
|
|
||||||
operator T const &() const { return this->data(); }
|
operator T const &() const
|
||||||
|
{
|
||||||
|
return wrapper_address()->data;
|
||||||
|
}
|
||||||
|
|
||||||
operator T&() { return this->data(); }
|
operator T&()
|
||||||
|
{
|
||||||
|
return wrapper_address()->data;
|
||||||
|
}
|
||||||
|
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
T const& get ( initialized<T> const& x )
|
||||||
|
{
|
||||||
|
return x.data() ;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
T& get ( initialized<T>& x )
|
||||||
|
{
|
||||||
|
return x.data() ;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
void swap ( initialized<T> & lhs, initialized<T> & rhs )
|
||||||
|
{
|
||||||
|
lhs.swap(rhs) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
class value_initialized
|
||||||
|
{
|
||||||
|
private :
|
||||||
|
|
||||||
|
// initialized<T> does value-initialization by default.
|
||||||
|
initialized<T> m_data;
|
||||||
|
|
||||||
|
public :
|
||||||
|
|
||||||
|
T const & data() const
|
||||||
|
{
|
||||||
|
return m_data.data();
|
||||||
|
}
|
||||||
|
|
||||||
|
T& data()
|
||||||
|
{
|
||||||
|
return m_data.data();
|
||||||
|
}
|
||||||
|
|
||||||
|
void swap(value_initialized & arg)
|
||||||
|
{
|
||||||
|
m_data.swap(arg.m_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
operator T const &() const
|
||||||
|
{
|
||||||
|
return m_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
operator T&()
|
||||||
|
{
|
||||||
|
return m_data;
|
||||||
|
}
|
||||||
|
} ;
|
||||||
|
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
@ -119,6 +196,7 @@ T const& get ( value_initialized<T> const& x )
|
|||||||
{
|
{
|
||||||
return x.data() ;
|
return x.data() ;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
T& get ( value_initialized<T>& x )
|
T& get ( value_initialized<T>& x )
|
||||||
{
|
{
|
||||||
@ -138,7 +216,7 @@ class initialized_value_t
|
|||||||
|
|
||||||
template <class T> operator T() const
|
template <class T> operator T() const
|
||||||
{
|
{
|
||||||
return get( value_initialized<T>() );
|
return initialized<T>().data();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -147,5 +225,8 @@ initialized_value_t const initialized_value = {} ;
|
|||||||
|
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
|
||||||
|
#ifdef BOOST_MSVC
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
116
initialized_test.cpp
Normal file
116
initialized_test.cpp
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
// Copyright 2010, Niels Dekker.
|
||||||
|
//
|
||||||
|
// 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)
|
||||||
|
//
|
||||||
|
// Test program for boost::initialized<T>.
|
||||||
|
//
|
||||||
|
// 2 May 2010 (Created) Niels Dekker
|
||||||
|
|
||||||
|
#include <boost/utility/value_init.hpp>
|
||||||
|
#include <boost/detail/lightweight_test.hpp>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
// Typical use case for boost::initialized<T>: A generic class that
|
||||||
|
// holds a value of type T, which must be initialized by either
|
||||||
|
// value-initialization or direct-initialization.
|
||||||
|
template <class T> class key_value_pair
|
||||||
|
{
|
||||||
|
std::string m_key;
|
||||||
|
boost::initialized<T> m_value;
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Value-initializes the object held by m_value.
|
||||||
|
key_value_pair() { }
|
||||||
|
|
||||||
|
// Value-initializes the object held by m_value.
|
||||||
|
explicit key_value_pair(const std::string& key)
|
||||||
|
:
|
||||||
|
m_key(key)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// Direct-initializes the object held by m_value.
|
||||||
|
key_value_pair(const std::string& key, const T& value)
|
||||||
|
:
|
||||||
|
m_key(key), m_value(value)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
const T& get_value() const
|
||||||
|
{
|
||||||
|
return m_value;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Tells whether the argument is value-initialized.
|
||||||
|
bool is_value_initialized(const int& arg)
|
||||||
|
{
|
||||||
|
return arg == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Tells whether the argument is value-initialized.
|
||||||
|
bool is_value_initialized(const std::string& arg)
|
||||||
|
{
|
||||||
|
return arg.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
struct foo
|
||||||
|
{
|
||||||
|
int data;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool operator==(const foo& lhs, const foo& rhs)
|
||||||
|
{
|
||||||
|
return lhs.data == rhs.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Tells whether the argument is value-initialized.
|
||||||
|
bool is_value_initialized(const foo& arg)
|
||||||
|
{
|
||||||
|
return arg.data == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
void test_key_value_pair(const T& magic_value)
|
||||||
|
{
|
||||||
|
// The value component of a default key_value_pair must be value-initialized.
|
||||||
|
key_value_pair<T> default_key_value_pair;
|
||||||
|
BOOST_TEST( is_value_initialized(default_key_value_pair.get_value() ) );
|
||||||
|
|
||||||
|
// The value component of a key_value_pair that only has its key explicitly specified
|
||||||
|
// must also be value-initialized.
|
||||||
|
BOOST_TEST( is_value_initialized(key_value_pair<T>("key").get_value()) );
|
||||||
|
|
||||||
|
// However, the value component of the following key_value_pair must be
|
||||||
|
// "magic_value", as it must be direct-initialized.
|
||||||
|
BOOST_TEST( key_value_pair<T>("key", magic_value).get_value() == magic_value );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Tests boost::initialize for a fundamental type, a type with a
|
||||||
|
// user-defined constructor, and a user-defined type without
|
||||||
|
// a user-defined constructor.
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
|
||||||
|
const int magic_number = 42;
|
||||||
|
test_key_value_pair(magic_number);
|
||||||
|
|
||||||
|
const std::string magic_string = "magic value";
|
||||||
|
test_key_value_pair(magic_string);
|
||||||
|
|
||||||
|
const foo magic_foo = { 42 };
|
||||||
|
test_key_value_pair(magic_foo);
|
||||||
|
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
33
initialized_test_fail1.cpp
Normal file
33
initialized_test_fail1.cpp
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
// Copyright 2010, Niels Dekker.
|
||||||
|
//
|
||||||
|
// 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)
|
||||||
|
//
|
||||||
|
// Test program for boost::initialized<T>. Must fail to compile.
|
||||||
|
//
|
||||||
|
// Initial: 2 May 2010
|
||||||
|
|
||||||
|
#include <boost/utility/value_init.hpp>
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
void direct_initialize_from_int()
|
||||||
|
{
|
||||||
|
// Okay: initialized<T> supports direct-initialization from T.
|
||||||
|
boost::initialized<int> direct_initialized_int(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void copy_initialize_from_int()
|
||||||
|
{
|
||||||
|
// The following line should not compile, because initialized<T>
|
||||||
|
// was not intended to supports copy-initialization from T.
|
||||||
|
boost::initialized<int> copy_initialized_int = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// This should fail to compile, so there is no need to call any function.
|
||||||
|
return 0;
|
||||||
|
}
|
37
initialized_test_fail2.cpp
Normal file
37
initialized_test_fail2.cpp
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
// Copyright 2010, Niels Dekker.
|
||||||
|
//
|
||||||
|
// 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)
|
||||||
|
//
|
||||||
|
// Test program for boost::initialized<T>. Must fail to compile.
|
||||||
|
//
|
||||||
|
// Initial: 2 May 2010
|
||||||
|
|
||||||
|
#include <boost/utility/value_init.hpp>
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
void from_value_initialized_to_initialized()
|
||||||
|
{
|
||||||
|
boost::value_initialized<int> value_initialized_int;
|
||||||
|
|
||||||
|
// Okay: initialized<T> can be initialized by value_initialized<T>.
|
||||||
|
boost::initialized<int> initialized_int(value_initialized_int);
|
||||||
|
}
|
||||||
|
|
||||||
|
void from_initialized_to_value_initialized()
|
||||||
|
{
|
||||||
|
boost::initialized<int> initialized_int(13);
|
||||||
|
|
||||||
|
// The following line should not compile, because initialized<T>
|
||||||
|
// should not be convertible to value_initialized<T>.
|
||||||
|
boost::value_initialized<int> value_initialized_int(initialized_int);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// This should fail to compile, so there is no need to call any function.
|
||||||
|
return 0;
|
||||||
|
}
|
@ -32,9 +32,12 @@ test-suite utility
|
|||||||
[ compile result_of_test.cpp ]
|
[ compile result_of_test.cpp ]
|
||||||
[ run ../shared_iterator_test.cpp ]
|
[ run ../shared_iterator_test.cpp ]
|
||||||
[ run ../value_init_test.cpp ]
|
[ run ../value_init_test.cpp ]
|
||||||
|
[ run ../initialized_test.cpp ]
|
||||||
[ compile-fail ../value_init_test_fail1.cpp ]
|
[ compile-fail ../value_init_test_fail1.cpp ]
|
||||||
[ compile-fail ../value_init_test_fail2.cpp ]
|
[ compile-fail ../value_init_test_fail2.cpp ]
|
||||||
[ compile-fail ../value_init_test_fail3.cpp ]
|
[ compile-fail ../value_init_test_fail3.cpp ]
|
||||||
|
[ compile-fail ../initialized_test_fail1.cpp ]
|
||||||
|
[ compile-fail ../initialized_test_fail2.cpp ]
|
||||||
[ run ../verify_test.cpp ]
|
[ run ../verify_test.cpp ]
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="#val_init"><code>template class value_initialized<T></code></a></li>
|
<li><a href="#val_init"><code>template class value_initialized<T></code></a></li>
|
||||||
|
<li><a href="#initialized"><code>template class initialized<T></code></a></li>
|
||||||
<li><a href="#initialized_value"><code>initialized_value</code></a></li>
|
<li><a href="#initialized_value"><code>initialized_value</code></a></li>
|
||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
@ -123,6 +124,12 @@ constructed by the following declaration:
|
|||||||
</pre>
|
</pre>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
|
The template <a href="#initialized"><code>initialized</code></a>
|
||||||
|
offers both value-initialization and direct-initialization.
|
||||||
|
It is especially useful as a data member type, allowing the very same object
|
||||||
|
to be either direct-initialized or value-initialized.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
The <code>const</code> object <a href="#initialized_value"><code>initialized_value</code></a>
|
The <code>const</code> object <a href="#initialized_value"><code>initialized_value</code></a>
|
||||||
allows value-initializing a variable as follows:
|
allows value-initializing a variable as follows:
|
||||||
<pre>
|
<pre>
|
||||||
@ -340,6 +347,52 @@ the wrapped object is always performed with the <code>get()</code> idiom:</p>
|
|||||||
|
|
||||||
<pre>value_initialized<int> x ;<br>get(x) = 1 ; // OK<br><br>value_initialized<int const> cx ;<br>get(x) = 1 ; // ERROR: Cannot modify a const object<br><br>value_initialized<int> const x_c ;<br>get(x_c) = 1 ; // ERROR: Cannot modify a const object<br><br>value_initialized<int const> const cx_c ;<br>get(cx_c) = 1 ; // ERROR: Cannot modify a const object<br></pre>
|
<pre>value_initialized<int> x ;<br>get(x) = 1 ; // OK<br><br>value_initialized<int const> cx ;<br>get(x) = 1 ; // ERROR: Cannot modify a const object<br><br>value_initialized<int> const x_c ;<br>get(x_c) = 1 ; // ERROR: Cannot modify a const object<br><br>value_initialized<int const> const cx_c ;<br>get(cx_c) = 1 ; // ERROR: Cannot modify a const object<br></pre>
|
||||||
|
|
||||||
|
<h2><a name="initialized"><code>template class initialized<T></code></a></h2>
|
||||||
|
|
||||||
|
<pre>namespace boost {<br><br>template<class T><br>class initialized<br>{
|
||||||
|
<br> public :
|
||||||
|
<br> initialized() : x() {}
|
||||||
|
<br> explicit initialized(T const & arg) : x(arg) {}
|
||||||
|
<br> operator T const &() const;
|
||||||
|
<br> operator T&();
|
||||||
|
<br> T const &data() const;
|
||||||
|
<br> T& data();
|
||||||
|
<br> void swap( value_initialized<T>& );
|
||||||
|
<br>
|
||||||
|
<br> private :
|
||||||
|
<br> <i>unspecified</i> x ;
|
||||||
|
<br>} ;
|
||||||
|
<br>
|
||||||
|
<br>template<class T>
|
||||||
|
<br>T const& get ( initialized<T> const& x );
|
||||||
|
<br>
|
||||||
|
<br>template<class T>
|
||||||
|
<br>T& get ( initialized<T>& x );
|
||||||
|
<br>
|
||||||
|
<br>} // namespace boost
|
||||||
|
<br></pre>
|
||||||
|
|
||||||
|
The template class <code>boost::initialized<T></code> supports both value-initialization
|
||||||
|
and direct-initialization, so its interface is a superset of the interface
|
||||||
|
of <code>value_initialized<T></code>: Its default-constructor
|
||||||
|
value-initializes the wrapped object just like the default-constructor of
|
||||||
|
<code>value_initialized<T></code>, but <code>boost::initialized<T></code>
|
||||||
|
also offers an extra <code>explicit</code>
|
||||||
|
constructor, which direct-initializes the wrapped object by the specified value.
|
||||||
|
<p>
|
||||||
|
|
||||||
|
<code>initialized<T></code> is especially useful when the wrapped
|
||||||
|
object must be either value-initialized or direct-initialized, depending on
|
||||||
|
runtime conditions. For example, <code>initialized<T></code> could
|
||||||
|
hold the value of a data member that may be value-initialized by some
|
||||||
|
constructors, and direct-initialized by others.
|
||||||
|
On the other hand, if it is known beforehand that the
|
||||||
|
object must <i>always</i> be value-initialized, <code>value_initialized<T></code>
|
||||||
|
may be preferable. And if the object must always be
|
||||||
|
direct-initialized, none of the two wrappers really needs to be used.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
|
||||||
<h2><a name="initialized_value"><code>initialized_value</code></a></h2>
|
<h2><a name="initialized_value"><code>initialized_value</code></a></h2>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
@ -399,6 +452,9 @@ Special thanks to Björn Karlsson who carefully edited and completed this do
|
|||||||
<p>value_initialized was reimplemented by Fernando Cacciola and Niels Dekker
|
<p>value_initialized was reimplemented by Fernando Cacciola and Niels Dekker
|
||||||
for Boost release version 1.35 (2008), offering a workaround to various compiler issues.
|
for Boost release version 1.35 (2008), offering a workaround to various compiler issues.
|
||||||
</p>
|
</p>
|
||||||
|
<p><code>boost::initialized</code> was very much inspired by feedback from Edward Diener and
|
||||||
|
Jeffrey Hellrung.
|
||||||
|
</p>
|
||||||
<p>initialized_value was written by Niels Dekker, and added to Boost release version 1.36 (2008).
|
<p>initialized_value was written by Niels Dekker, and added to Boost release version 1.36 (2008).
|
||||||
</p>
|
</p>
|
||||||
<p>Developed by <a href="mailto:fernando_cacciola@hotmail.com">Fernando Cacciola</a>,
|
<p>Developed by <a href="mailto:fernando_cacciola@hotmail.com">Fernando Cacciola</a>,
|
||||||
@ -407,9 +463,9 @@ for Boost release version 1.35 (2008), offering a workaround to various compiler
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
<p>Revised 03 October 2009</p>
|
<p>Revised 1 May 2010</p>
|
||||||
|
|
||||||
<p>© Copyright Fernando Cacciola, 2002, 2009.</p>
|
<p>© Copyright Fernando Cacciola, 2002 - 2010.</p>
|
||||||
|
|
||||||
<p>Distributed under the Boost Software License, Version 1.0. See
|
<p>Distributed under the Boost Software License, Version 1.0. See
|
||||||
<a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a></p>
|
<a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a></p>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user