diff --git a/CMakeLists.txt b/CMakeLists.txt index 6f760feef..150138900 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -50,11 +50,10 @@ endif (${CMAKE_CXX_COMPILER_ID} MATCHES "Clang") # ================================================================================ -# Issues with boost::any on older versions with C++11 enabled. -set(BOOST_MIN_VERSION 1.55) -IF(CMAKE_COMPILER_IS_GNUCXX AND CMAKE_COMPILER_VERSION VERSION_LESS 4.7) - UNSET(BOOST_MIN_VERSION) # For Ubuntu 12.04 -ENDIF(CMAKE_COMPILER_IS_GNUCXX AND CMAKE_COMPILER_VERSION VERSION_LESS 4.7) +# Allow developers to use Boost < 1.48 +if(NOT ${BOOST_MIN_VERSION}) + set(BOOST_MIN_VERSION 1.48) +endif() # Enabled C++11 for Freecad 0.17 and later IF(FREECAD_VERSION VERSION_GREATER 0.16) diff --git a/src/App/CMakeLists.txt b/src/App/CMakeLists.txt index 1fd9d474a..feabe415d 100644 --- a/src/App/CMakeLists.txt +++ b/src/App/CMakeLists.txt @@ -12,6 +12,8 @@ IF(DOCDIR) add_definitions(-DDOCDIR="${DOCDIR}") ENDIF(DOCDIR) +add_definitions(-DBOOST_${Boost_VERSION}) + include_directories( ${CMAKE_BINARY_DIR}/src ${CMAKE_SOURCE_DIR}/src diff --git a/src/App/ObjectIdentifier.h b/src/App/ObjectIdentifier.h index d28b1cfd4..5c207e0c0 100644 --- a/src/App/ObjectIdentifier.h +++ b/src/App/ObjectIdentifier.h @@ -26,7 +26,11 @@ #include #include +#ifndef BOOST_105400 #include +#else +#include +#endif namespace App { diff --git a/src/App/Property.h b/src/App/Property.h index b0855f3a7..79a1e21f7 100644 --- a/src/App/Property.h +++ b/src/App/Property.h @@ -27,7 +27,11 @@ // Std. configurations #include -#include +#ifndef BOOST_105400 +#include +#else +#include +#endif #include #include diff --git a/src/Mod/Assembly/App/CMakeLists.txt b/src/Mod/Assembly/App/CMakeLists.txt index 9d7eaf1bb..7efcbff60 100644 --- a/src/Mod/Assembly/App/CMakeLists.txt +++ b/src/Mod/Assembly/App/CMakeLists.txt @@ -4,6 +4,8 @@ else(MSVC) add_definitions(-DHAVE_LIMITS_H -DHAVE_CONFIG_H) endif(MSVC) +add_definitions(-DBOOST_${Boost_VERSION}) + include_directories( ${CMAKE_SOURCE_DIR}/src ${CMAKE_BINARY_DIR}/src diff --git a/src/Mod/Assembly/App/opendcm/core/constraint.hpp b/src/Mod/Assembly/App/opendcm/core/constraint.hpp index 7fcc1b9d5..0654adedc 100644 --- a/src/Mod/Assembly/App/opendcm/core/constraint.hpp +++ b/src/Mod/Assembly/App/opendcm/core/constraint.hpp @@ -32,7 +32,11 @@ #include #include +#ifndef BOOST_105400 #include +#else +#include +#endif #include #include diff --git a/src/boost_any_1_55.hpp b/src/boost_any_1_55.hpp new file mode 100644 index 000000000..3edd2390f --- /dev/null +++ b/src/boost_any_1_55.hpp @@ -0,0 +1,357 @@ +// See http://www.boost.org/libs/any for Documentation. + +#ifndef BOOST_ANY_INCLUDED +#define BOOST_ANY_INCLUDED + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// what: variant type boost::any +// who: contributed by Kevlin Henney, +// with features contributed and bugs found by +// Antony Polukhin, Ed Brey, Mark Rodgers, +// Peter Dimov, and James Curran +// when: July 2001, April 2013 - May 2013 + +#include +#include + +#include "boost/config.hpp" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// See boost/python/type_id.hpp +// TODO: add BOOST_TYPEID_COMPARE_BY_NAME to config.hpp +# if (defined(__GNUC__) && __GNUC__ >= 3) \ + || defined(_AIX) \ + || ( defined(__sgi) && defined(__host_mips)) \ + || (defined(__hpux) && defined(__HP_aCC)) \ + || (defined(linux) && defined(__INTEL_COMPILER) && defined(__ICC)) +# define BOOST_AUX_ANY_TYPE_ID_NAME +#include +# endif + +#if defined(_MSC_VER) +#pragma warning(push) +#pragma warning(disable: 4172) // Mistakenly warns: returning address of local variable or temporary +#endif + +namespace boost +{ + class any + { + public: // structors + + any() BOOST_NOEXCEPT + : content(0) + { + } + + template + any(const ValueType & value) + : content(new holder::type>(value)) + { + } + + any(const any & other) + : content(other.content ? other.content->clone() : 0) + { + } + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + // Move constructor + any(any&& other) BOOST_NOEXCEPT + : content(other.content) + { + other.content = 0; + } + + // Perfect forwarding of ValueType + template + any(ValueType&& value + , typename boost::disable_if >::type* = 0 // disable if value has type `any&` + , typename boost::disable_if >::type* = 0) // disable if value has type `const ValueType&&` + : content(new holder< typename decay::type >(static_cast(value))) + { + } +#endif + + ~any() BOOST_NOEXCEPT + { + delete content; + } + + public: // modifiers + + any & swap(any & rhs) BOOST_NOEXCEPT + { + std::swap(content, rhs.content); + return *this; + } + + +#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES + template + any & operator=(const ValueType & rhs) + { + any(rhs).swap(*this); + return *this; + } + + any & operator=(any rhs) + { + any(rhs).swap(*this); + return *this; + } + +#else + any & operator=(const any& rhs) + { + any(rhs).swap(*this); + return *this; + } + + // move assignement + any & operator=(any&& rhs) BOOST_NOEXCEPT + { + rhs.swap(*this); + any().swap(rhs); + return *this; + } + + // Perfect forwarding of ValueType + template + any & operator=(ValueType&& rhs) + { + any(static_cast(rhs)).swap(*this); + return *this; + } +#endif + + public: // queries + + bool empty() const BOOST_NOEXCEPT + { + return !content; + } + + void clear() BOOST_NOEXCEPT + { + any().swap(*this); + } + + const std::type_info & type() const BOOST_NOEXCEPT + { + return content ? content->type() : typeid(void); + } + +#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS + private: // types +#else + public: // types (public so any_cast can be non-friend) +#endif + + class placeholder + { + public: // structors + + virtual ~placeholder() + { + } + + public: // queries + + virtual const std::type_info & type() const BOOST_NOEXCEPT = 0; + + virtual placeholder * clone() const = 0; + + }; + + template + class holder : public placeholder + { + public: // structors + + holder(const ValueType & value) + : held(value) + { + } + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + holder(ValueType&& value) + : held(static_cast< ValueType&& >(value)) + { + } +#endif + public: // queries + + virtual const std::type_info & type() const BOOST_NOEXCEPT + { + return typeid(ValueType); + } + + virtual placeholder * clone() const + { + return new holder(held); + } + + public: // representation + + ValueType held; + + private: // intentionally left unimplemented + holder & operator=(const holder &); + }; + +#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS + + private: // representation + + template + friend ValueType * any_cast(any *) BOOST_NOEXCEPT; + + template + friend ValueType * unsafe_any_cast(any *) BOOST_NOEXCEPT; + +#else + + public: // representation (public so any_cast can be non-friend) + +#endif + + placeholder * content; + + }; + + inline void swap(any & lhs, any & rhs) BOOST_NOEXCEPT + { + lhs.swap(rhs); + } + + class BOOST_SYMBOL_VISIBLE bad_any_cast : public std::bad_cast + { + public: + virtual const char * what() const BOOST_NOEXCEPT_OR_NOTHROW + { + return "boost::bad_any_cast: " + "failed conversion using boost::any_cast"; + } + }; + + template + ValueType * any_cast(any * operand) BOOST_NOEXCEPT + { + return operand && +#ifdef BOOST_AUX_ANY_TYPE_ID_NAME + std::strcmp(operand->type().name(), typeid(ValueType).name()) == 0 +#else + operand->type() == typeid(ValueType) +#endif + ? &static_cast *>(operand->content)->held + : 0; + } + + template + inline const ValueType * any_cast(const any * operand) BOOST_NOEXCEPT + { + return any_cast(const_cast(operand)); + } + + template + ValueType any_cast(any & operand) + { + typedef BOOST_DEDUCED_TYPENAME remove_reference::type nonref; + +#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + // If 'nonref' is still reference type, it means the user has not + // specialized 'remove_reference'. + + // Please use BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION macro + // to generate specialization of remove_reference for your class + // See type traits library documentation for details + BOOST_STATIC_ASSERT(!is_reference::value); +#endif + + nonref * result = any_cast(&operand); + if(!result) + boost::throw_exception(bad_any_cast()); + + // Attempt to avoid construction of a temporary object in cases when + // `ValueType` is not a reference. Example: + // `static_cast(*result);` + // which is equal to `std::string(*result);` + typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_< + boost::is_reference, + ValueType, + BOOST_DEDUCED_TYPENAME boost::add_reference::type + >::type ref_type; + + return static_cast(*result); + } + + template + inline ValueType any_cast(const any & operand) + { + typedef BOOST_DEDUCED_TYPENAME remove_reference::type nonref; + +#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + // The comment in the above version of 'any_cast' explains when this + // assert is fired and what to do. + BOOST_STATIC_ASSERT(!is_reference::value); +#endif + + return any_cast(const_cast(operand)); + } + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + template + inline ValueType&& any_cast(any&& operand) + { + BOOST_STATIC_ASSERT_MSG( + boost::is_rvalue_reference::value + || boost::is_const< typename boost::remove_reference::type >::value, + "boost::any_cast shall not be used for getting nonconst references to temporary objects" + ); + return any_cast(operand); + } +#endif + + + // Note: The "unsafe" versions of any_cast are not part of the + // public interface and may be removed at any time. They are + // required where we know what type is stored in the any and can't + // use typeid() comparison, e.g., when our types may travel across + // different shared libraries. + template + inline ValueType * unsafe_any_cast(any * operand) BOOST_NOEXCEPT + { + return &static_cast *>(operand->content)->held; + } + + template + inline const ValueType * unsafe_any_cast(const any * operand) BOOST_NOEXCEPT + { + return unsafe_any_cast(const_cast(operand)); + } +} + +// Copyright Kevlin Henney, 2000, 2001, 2002. All rights reserved. +// +// 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) + +#if defined(_MSC_VER) +#pragma warning(pop) +#endif + +#endif