diff options
Diffstat (limited to 'boost/flyweight/key_value.hpp')
-rw-r--r-- | boost/flyweight/key_value.hpp | 93 |
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 */ |