diff --git a/doc/internals/polynomial.qbk b/doc/internals/polynomial.qbk index 18ce44cb6..37caade60 100644 --- a/doc/internals/polynomial.qbk +++ b/doc/internals/polynomial.qbk @@ -24,7 +24,11 @@ template polynomial(I first, I last); template - explicit polynomial(const U& point); + explicit polynomial(const U& point, + typename boost::enable_if >::type* = 0); + template + explicit polynomial(const Range& r, + typename boost::enable_if >::type* = 0); // C++14 polynomial(std::initializer_list l); // C++11 polynomial(std::vector&& p); diff --git a/include/boost/math/tools/detail/is_const_iterable.hpp b/include/boost/math/tools/detail/is_const_iterable.hpp new file mode 100644 index 000000000..805b66e22 --- /dev/null +++ b/include/boost/math/tools/detail/is_const_iterable.hpp @@ -0,0 +1,40 @@ +// (C) Copyright John Maddock 2018. +// Use, modification and distribution are subject to 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) + +#ifndef BOOST_MATH_TOOLS_IS_CONST_ITERABLE_HPP +#define BOOST_MATH_TOOLS_IS_CONST_ITERABLE_HPP + +#if !defined(BOOST_NO_CXX14_VARIABLE_TEMPLATES) && !defined(BOOST_NO_CXX11_DECLTYPE) && !defined(BOOST_NO_CXX11_SFINAE_EXPR) + +#define BOOST_MATH_HAS_IS_CONST_ITERABLE + +#include +#include + +namespace boost { + namespace math { + namespace tools { + namespace detail { + + template + using begin_t = decltype(std::declval().begin()); + template + using end_t = decltype(std::declval().end()); + template + using const_iterator_t = typename T::const_iterator; + + template + struct is_const_iterable + : public boost::integral_constant::value + && boost::is_detected::value + && boost::is_detected::value + > {}; + +} } } } + +#endif + +#endif // BOOST_MATH_TOOLS_IS_CONST_ITERABLE_HPP diff --git a/include/boost/math/tools/polynomial.hpp b/include/boost/math/tools/polynomial.hpp index 792fe6d26..357f1313f 100644 --- a/include/boost/math/tools/polynomial.hpp +++ b/include/boost/math/tools/polynomial.hpp @@ -23,6 +23,8 @@ #include #include #include +#include +#include #include #include @@ -309,7 +311,7 @@ public: #endif template - explicit polynomial(const U& point) + explicit polynomial(const U& point, typename boost::enable_if >::type* = 0) { if (point != U(0)) m_data.push_back(point); @@ -334,7 +336,13 @@ public: m_data[i] = boost::math::tools::real_cast(p[i]); } } - +#ifdef BOOST_MATH_HAS_IS_CONST_ITERABLE + template + explicit polynomial(const Range& r, typename boost::enable_if >::type* = 0) + : polynomial(r.begin(), r.end()) + { + } +#endif #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) && !BOOST_WORKAROUND(BOOST_GCC_VERSION, < 40500) polynomial(std::initializer_list l) : polynomial(std::begin(l), std::end(l)) { diff --git a/test/test_polynomial.cpp b/test/test_polynomial.cpp index 920716f41..503d0e2a4 100644 --- a/test/test_polynomial.cpp +++ b/test/test_polynomial.cpp @@ -79,6 +79,25 @@ BOOST_AUTO_TEST_CASE( test_construction ) BOOST_CHECK_EQUAL(a, b); } +#ifdef BOOST_MATH_HAS_IS_CONST_ITERABLE + +#include +#include + +BOOST_AUTO_TEST_CASE(test_range_construction) +{ + std::list l{ 1, 2, 3, 4 }; + std::array a{ 3, 4, 5, 6 }; + polynomial p1{ 1, 2, 3, 4 }; + polynomial p2{ 3, 4, 5, 6 }; + + polynomial p3(l); + polynomial p4(a); + + BOOST_CHECK_EQUAL(p1, p3); + BOOST_CHECK_EQUAL(p2, p4); +} +#endif #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) && !BOOST_WORKAROUND(BOOST_GCC_VERSION, < 40500) BOOST_AUTO_TEST_CASE( test_initializer_list_construction )