summaryrefslogtreecommitdiff
path: root/boost/flyweight/key_value.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/flyweight/key_value.hpp')
-rw-r--r--boost/flyweight/key_value.hpp93
1 files changed, 78 insertions, 15 deletions
diff --git a/boost/flyweight/key_value.hpp b/boost/flyweight/key_value.hpp
index 5ac1c0d57d..eb58d152cb 100644
--- a/boost/flyweight/key_value.hpp
+++ b/boost/flyweight/key_value.hpp
@@ -1,4 +1,4 @@
-/* Copyright 2006-2008 Joaquin M Lopez Munoz.
+/* Copyright 2006-2014 Joaquin M Lopez Munoz.
* 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)
@@ -9,14 +9,16 @@
#ifndef BOOST_FLYWEIGHT_KEY_VALUE_HPP
#define BOOST_FLYWEIGHT_KEY_VALUE_HPP
-#if defined(_MSC_VER)&&(_MSC_VER>=1200)
+#if defined(_MSC_VER)
#pragma once
#endif
+#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
+#include <boost/detail/workaround.hpp>
+#include <boost/flyweight/detail/perfect_fwd.hpp>
#include <boost/flyweight/detail/value_tag.hpp>
#include <boost/flyweight/key_value_fwd.hpp>
#include <boost/mpl/assert.hpp>
-#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/type_traits/aligned_storage.hpp>
#include <boost/type_traits/alignment_of.hpp>
#include <boost/type_traits/is_same.hpp>
@@ -54,21 +56,34 @@ struct optimized_key_value:value_marker
public:
/* template ctors */
-#define BOOST_FLYWEIGHT_PERFECT_FWD_NAME explicit rep_type
-#define BOOST_FLYWEIGHT_PERFECT_FWD_BODY(n) \
- :value_ptr(0) \
-{ \
- new(spc_ptr())key_type(BOOST_PP_ENUM_PARAMS(n,t)); \
+#define BOOST_FLYWEIGHT_PERFECT_FWD_CTR_BODY(args) \
+ :value_ptr(0) \
+{ \
+ new(spc_ptr())key_type(BOOST_FLYWEIGHT_FORWARD(args)); \
}
-#include <boost/flyweight/detail/perfect_fwd.hpp>
- rep_type(const value_type& x):value_ptr(&x){}
+ BOOST_FLYWEIGHT_PERFECT_FWD(
+ explicit rep_type,
+ BOOST_FLYWEIGHT_PERFECT_FWD_CTR_BODY)
+
+#undef BOOST_FLYWEIGHT_PERFECT_FWD_CTR_BODY
rep_type(const rep_type& x):value_ptr(x.value_ptr)
{
if(!x.value_ptr)new(key_ptr())key_type(*x.key_ptr());
}
+ rep_type(const value_type& x):value_ptr(&x){}
+
+#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+ rep_type(rep_type&& x):value_ptr(x.value_ptr)
+ {
+ if(!x.value_ptr)new(key_ptr())key_type(std::move(*x.key_ptr()));
+ }
+
+ rep_type(value_type&& x):value_ptr(&x){}
+#endif
+
~rep_type()
{
if(!value_ptr) key_ptr()->~key_type();
@@ -113,7 +128,12 @@ struct optimized_key_value:value_marker
if(!value_cted()){
/* value_ptr must be ==0, oherwise copy_value would have been called */
+#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+ key_type k(std::move(*key_ptr()));
+#else
key_type k(*key_ptr());
+#endif
+
key_ptr()->~key_type();
value_ptr= /* guarantees key won't be re-dted at ~rep_type if the */
static_cast<value_type*>(spc_ptr())+1; /* next statement throws */
@@ -126,6 +146,14 @@ struct optimized_key_value:value_marker
if(!value_cted())value_ptr=new(spc_ptr())value_type(*value_ptr);
}
+#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+ void move_value()const
+ {
+ if(!value_cted())value_ptr=
+ new(spc_ptr())value_type(std::move(const_cast<value_type&>(*value_ptr)));
+ }
+#endif
+
mutable typename boost::aligned_storage<
(sizeof(key_type)>sizeof(value_type))?
sizeof(key_type):sizeof(value_type),
@@ -146,6 +174,13 @@ struct optimized_key_value:value_marker
{
r.copy_value();
}
+
+#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+ static void move_value(const rep_type& r)
+ {
+ r.move_value();
+ }
+#endif
};
template<typename Key,typename Value>
@@ -159,14 +194,33 @@ struct regular_key_value:value_marker
public:
/* template ctors */
-#define BOOST_FLYWEIGHT_PERFECT_FWD_NAME explicit rep_type
-#define BOOST_FLYWEIGHT_PERFECT_FWD_BODY(n) \
- :key(BOOST_PP_ENUM_PARAMS(n,t)),value_ptr(0){}
-#include <boost/flyweight/detail/perfect_fwd.hpp>
+#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)&&\
+ !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)&&\
+ BOOST_WORKAROUND(__GNUC__,<=4)&&(__GNUC__<4||__GNUC_MINOR__<=4)
- rep_type(const value_type& x):key(no_key_from_value_failure()){}
+/* GCC 4.4.2 (and probably prior) bug: the default ctor generated by the
+ * variadic temmplate ctor below fails to value-initialize key.
+ */
+
+ rep_type():key(),value_ptr(0){}
+#endif
+
+#define BOOST_FLYWEIGHT_PERFECT_FWD_CTR_BODY(args) \
+ :key(BOOST_FLYWEIGHT_FORWARD(args)),value_ptr(0){}
+
+ BOOST_FLYWEIGHT_PERFECT_FWD(
+ explicit rep_type,
+ BOOST_FLYWEIGHT_PERFECT_FWD_CTR_BODY)
+
+#undef BOOST_FLYWEIGHT_PERFECT_FWD_CTR_BODY
rep_type(const rep_type& x):key(x.key),value_ptr(0){}
+ rep_type(const value_type& x):key(no_key_from_value_failure()){}
+
+#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+ rep_type(rep_type&& x):key(std::move(x.key)),value_ptr(0){}
+ rep_type(value_type&& x):key(no_key_from_value_failure()){}
+#endif
~rep_type()
{
@@ -217,7 +271,16 @@ struct regular_key_value:value_marker
r.construct_value();
}
+ /* copy_value() and move_value() can't really ever be called, provided to avoid
+ * compile errors (it is the no_key_from_value_failure compile error we want to
+ * appear in these cases).
+ */
+
static void copy_value(const rep_type&){}
+
+#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+ static void move_value(const rep_type&){}
+#endif
};
} /* namespace flyweights::detail */