diff --git a/include/boost/container/detail/is_constructible.hpp b/include/boost/container/detail/is_constructible.hpp new file mode 100644 index 0000000..35ceaec --- /dev/null +++ b/include/boost/container/detail/is_constructible.hpp @@ -0,0 +1,180 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2015. 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) +// +// See http://www.boost.org/libs/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_CONTAINER_DETAIL_IS_CONSTRUCTIBLE_HPP +#define BOOST_CONTAINER_DETAIL_IS_CONSTRUCTIBLE_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include + +#include // for size_t +#include //declval + +namespace boost_container_is_constructible { + + typedef char yes_type; + struct no_type { char padding[8]; }; + + template struct enable_if {}; + template struct enable_if { typedef T type; }; + template struct t_enable { typedef T type; }; + +} //namespace boost_container_is_constructible { + +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_DECLTYPE) + + namespace boost { + namespace container { + + template + struct is_constructible\ + { + private: + typedef char yes_type; + struct no_type { char padding[8]; }; + + template + static decltype( new U(boost::move_detail::declval()...), yes_type() ) test(int); + + template + static no_type test(...); + + public: + static const bool value = sizeof(test(0)) == sizeof(yes_type); + }; + + } //namespace container { + } //namespace boost { + +#else //Use macro expansion + + #include + + #if defined(BOOST_NO_CXX11_DECLTYPE) + + namespace boost_container_is_constructible { + + // Example for N == 2 + // + //template + //struct is_constructible2 + //{ + // private: + // template + // static char test( typename enable_if< (sizeof( new U(boost::move_detail::declval(), boost::move_detail::declval()))!= 0), int>::type ); + // + // template + // static no_type test(...); + // + // public: + // static const bool value = sizeof(test(0)) == sizeof(yes_type); + //}; + #define BOOST_INTRUSIVE_IS_CONSTRUCTIBLE_IMPL(N) \ + template \ + struct BOOST_MOVE_CAT(is_constructible_impl, N)\ + {\ + private:\ + template \ + static yes_type test( typename enable_if< (sizeof( new U(BOOST_MOVE_DECLVAL##N))!= 0), int>::type );\ + \ + template \ + static no_type test(...);\ + \ + public:\ + static const bool value = sizeof(test(0)) == sizeof(yes_type);\ + };\ + // + BOOST_MOVE_ITERATE_0TO9(BOOST_INTRUSIVE_IS_CONSTRUCTIBLE_IMPL) + #undef BOOST_INTRUSIVE_IS_CONSTRUCTIBLE_IMPL + + }// namespace boost_container_is_constructible { + + #else + + namespace boost_container_is_constructible { + + // Example for N == 2 + // + //template + //struct is_constructible2 + //{ + // private: + // template(), boost::move_detail::declval()) ) > + // static char test( int ); + // + // template + // static no_type test(...); + // + // public: + // static const bool value = sizeof(test(0)) == sizeof(yes_type); + //}; + + #define BOOST_INTRUSIVE_IS_CONSTRUCTIBLE_IMPL(N) \ + template \ + struct BOOST_MOVE_CAT(is_constructible_impl, N)\ + {\ + private:\ + template \ + static decltype( new U(BOOST_MOVE_DECLVAL##N), yes_type() ) test(int);\ + \ + template \ + static no_type test(...);\ + \ + public:\ + static const bool value = sizeof(test(0)) == sizeof(yes_type);\ + };\ + // + BOOST_MOVE_ITERATE_0TO9(BOOST_INTRUSIVE_IS_CONSTRUCTIBLE_IMPL) + #undef BOOST_INTRUSIVE_IS_CONSTRUCTIBLE_IMPL + + }// namespace boost_container_is_constructible { + + #endif + + namespace boost { + namespace container { + + template + struct is_constructible; + + // Example for N == 2 + // + //template + //struct is_constructible + // + // : boost_container_is_constructible::is_constructible_impl2 + //{}; + + #define BOOST_INTRUSIVE_IS_CONSTRUCTIBLE(N) \ + template \ + struct is_constructible\ + \ + : boost_container_is_constructible::is_constructible_impl##N\ + {};\ + // + BOOST_MOVE_ITERATE_0TO9(BOOST_INTRUSIVE_IS_CONSTRUCTIBLE) + #undef BOOST_INTRUSIVE_IS_CONSTRUCTIBLE + + } //namespace container { + } //namespace boost { + +#endif + +#include + +#endif //BOOST_CONTAINER_DETAIL_IS_CONSTRUCTIBLE_HPP diff --git a/test/is_constructible_test.cpp b/test/is_constructible_test.cpp new file mode 100644 index 0000000..e891618 --- /dev/null +++ b/test/is_constructible_test.cpp @@ -0,0 +1,63 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2025-2025. 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) +// +// See http://www.boost.org/libs/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#include +#include + +struct Point { + int x, y; + Point(); + Point(int); + Point(int, int); + Point(int, int, int); + Point(int, int, int, int); + Point(int, int, int, int, int, int, int, int); +}; + +struct Point2 +{ + Point2(int*); +}; + +int main() +{ + // 0 args + BOOST_CONTAINER_STATIC_ASSERT((true ==boost::container::is_constructible::value)); + BOOST_CONTAINER_STATIC_ASSERT((true ==boost::container::is_constructible >::value)); + BOOST_CONTAINER_STATIC_ASSERT((false ==boost::container::is_constructible::value)); + + // 1 args + BOOST_CONTAINER_STATIC_ASSERT((true ==boost::container::is_constructible::value)); + BOOST_CONTAINER_STATIC_ASSERT((true ==boost::container::is_constructible, std::size_t>::value)); + BOOST_CONTAINER_STATIC_ASSERT((false ==boost::container::is_constructible, int*>::value)); + BOOST_CONTAINER_STATIC_ASSERT((false ==boost::container::is_constructible::value)); + BOOST_CONTAINER_STATIC_ASSERT((false ==boost::container::is_constructible::value)); + + // 2 args + BOOST_CONTAINER_STATIC_ASSERT((true ==boost::container::is_constructible::value)); + BOOST_CONTAINER_STATIC_ASSERT((true ==boost::container::is_constructible, size_t, int>::value)); + BOOST_CONTAINER_STATIC_ASSERT((false ==boost::container::is_constructible::value)); + + // 3 args + BOOST_CONTAINER_STATIC_ASSERT((true ==boost::container::is_constructible::value)); + BOOST_CONTAINER_STATIC_ASSERT((true ==boost::container::is_constructible, int*, int*, boost::container::vector::allocator_type>::value)); + BOOST_CONTAINER_STATIC_ASSERT((false ==boost::container::is_constructible::value)); + + // 4 args + BOOST_CONTAINER_STATIC_ASSERT((true ==boost::container::is_constructible::value)); + BOOST_CONTAINER_STATIC_ASSERT((false ==boost::container::is_constructible::value)); + + // 8 args + BOOST_CONTAINER_STATIC_ASSERT((true ==boost::container::is_constructible::value)); + BOOST_CONTAINER_STATIC_ASSERT((false ==boost::container::is_constructible::value)); + + return 0; +} +