diff --git a/include/boost/container/flat_set.hpp b/include/boost/container/flat_set.hpp index 79b77c3..ef33f07 100644 --- a/include/boost/container/flat_set.hpp +++ b/include/boost/container/flat_set.hpp @@ -28,6 +28,9 @@ #include #include +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) +#include +#endif namespace boost { namespace container { @@ -145,6 +148,37 @@ class flat_set : base_t(ordered_range, first, last, comp, a) {} +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + //! Effects: Constructs an empty container using the specified comparison object and + //! allocator, and inserts elements from the range [il.begin(), il.end()). + //! + //! Complexity: Linear in N if the range [il.begin(), il.end()) is already sorted using + //! comp and otherwise N logN, where N is il.begin() - il.end(). + flat_set(std::initializer_list il, const Compare& comp = Compare(), + const allocator_type& a = allocator_type()) + : base_t(true, il.begin(), il.end(), comp, a) + { + + } + + //! Effects: Constructs an empty container using the specified comparison object and + //! allocator, and inserts elements from the ordered unique range [il.begin(), il.end()). This function + //! is more efficient than the normal range creation for ordered ranges. + //! + //! Requires: [il.begin(), il.end()) must be ordered according to the predicate and must be + //! unique values. + //! + //! Complexity: Linear in N. + //! + //! Note: Non-standard extension. + flat_set(ordered_unique_range_t, std::initializer_list il, + const Compare& comp = Compare(), const allocator_type& a = allocator_type()) + : base_t(ordered_range, il.begin(), il.end(), comp, a) + { + + } +#endif + //! Effects: Copy constructs the container. //! //! Complexity: Linear in x.size(). @@ -192,6 +226,18 @@ class flat_set BOOST_CONTAINER_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_move_assignment::value) { return static_cast(this->base_t::operator=(boost::move(static_cast(x)))); } +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + //! Effects: Copy all elements from il to *this. + //! + //! Complexity: Linear in il.size(). + flat_set& operator=(std::initializer_list il) + { + this->clear(); + this->insert(il.begin(), il.end()); + return *this; + } +#endif + #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED //! Effects: Returns a copy of the Allocator that //! was passed to the object's constructor. @@ -504,6 +550,31 @@ class flat_set void insert(ordered_unique_range_t, InputIterator first, InputIterator last) { this->base_t::insert_unique(ordered_unique_range, first, last); } +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + //! Effects: inserts each element from the range [il.begin(), il.end()) if and only + //! if there is no element with key equivalent to the key of that element. + //! + //! Complexity: At most N log(size()+N) (N is the distance from il.begin() to il.end()) + //! search time plus N*size() insertion time. + //! + //! Note: If an element is inserted it might invalidate elements. + void insert(std::initializer_list il) + { this->base_t::insert_unique(il.begin(), il.end()); } + + //! Requires: Range [il.begin(), il.end()) must be ordered according to the predicate + //! and must be unique values. + //! + //! Effects: inserts each element from the range [il.begin(), il.end()) .This function + //! is more efficient than the normal range creation for ordered ranges. + //! + //! Complexity: At most N log(size()+N) (N is the distance from il.begin() to il.end()) + //! search time plus N*size() insertion time. + //! + //! Note: Non-standard extension. If an element is inserted it might invalidate elements. + void insert(ordered_unique_range_t, std::initializer_list il) + { this->base_t::insert_unique(ordered_unique_range, il.begin(), il.end()); } +#endif + #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) //! Effects: Erases the element pointed to by p. @@ -784,6 +855,20 @@ class flat_multiset : base_t(ordered_range, first, last, comp, a) {} +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + //! @copydoc ::boost::container::flat_set::flat_set(std::initializer_list, const Compare& comp, const allocator_type&) + flat_multiset(std::initializer_list il, const Compare& comp = Compare(), + const allocator_type& a = allocator_type()) + : base_t(false, il.begin(), il.end(), comp, a) + {} + + //! @copydoc ::boost::container::flat_set::flat_set(ordered_unique_range_t, std::initializer_list, const Compare& comp, const allocator_type&) + flat_multiset(ordered_unique_range_t, std::initializer_list il, + const Compare& comp = Compare(), const allocator_type& a = allocator_type()) + : base_t(ordered_range, il.begin(), il.end(), comp, a) + {} +#endif + //! @copydoc ::boost::container::flat_set::flat_set(const flat_set &) flat_multiset(const flat_multiset& x) : base_t(static_cast(x)) @@ -813,6 +898,16 @@ class flat_multiset BOOST_CONTAINER_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_move_assignment::value) { return static_cast(this->base_t::operator=(boost::move(static_cast(mx)))); } +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + //! @copydoc ::boost::container::flat_set::operator=(std::initializer_list) + flat_multiset& operator=(std::initializer_list il) + { + this->clear(); + this->insert(il.begin(), il.end()); + return *this; + } +#endif + #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) //! @copydoc ::boost::container::flat_set::get_allocator() @@ -1009,6 +1104,29 @@ class flat_multiset void insert(ordered_range_t, InputIterator first, InputIterator last) { this->base_t::insert_equal(ordered_range, first, last); } +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + //! Effects: inserts each element from the range [il.begin(), il.end()). + //! + //! Complexity: At most N log(size()+N) (N is the distance from first to last) + //! search time plus N*size() insertion time. + //! + //! Note: If an element is inserted it might invalidate elements. + void insert(std::initializer_list il) + { this->base_t::insert_equal(il.begin(), il.end()); } + + //! Requires: Range [il.begin(), il.end()) must be ordered according to the predicate. + //! + //! Effects: inserts each element from the range [il.begin(), il.end()). This function + //! is more efficient than the normal range creation for ordered ranges. + //! + //! Complexity: At most N log(size()+N) (N is the distance from il.begin() to il.end()) + //! search time plus N*size() insertion time. + //! + //! Note: Non-standard extension. If an element is inserted it might invalidate elements. + void insert(ordered_range_t, std::initializer_list il) + { this->base_t::insert_equal(ordered_range, il.begin(), il.end()); } +#endif + #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) //! @copydoc ::boost::container::flat_set::erase(const_iterator) diff --git a/test/flat_set_test.cpp b/test/flat_set_test.cpp index 541fb27..4237549 100644 --- a/test/flat_set_test.cpp +++ b/test/flat_set_test.cpp @@ -412,6 +412,39 @@ int test_set_variants() } +template +bool test_support_for_initialization_list_for() +{ +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + const std::initializer_list il + = {1, 2}; + + const FlatSetType expected(il.begin(), il.end()); + { + const FlatSetType sil = il; + if (sil != expected) + return false; + + const FlatSetType sil_ordered(ordered_unique_range, il); + if(sil_ordered != expected) + return false; + + FlatSetType sil_assign = {99}; + sil_assign = il; + if(sil_assign != expected) + return false; + } + { + FlatSetType sil; + sil.insert(il); + if(sil != expected) + return false; + } + return true; +#endif + return true; +} + int main() { using namespace boost::container::test; @@ -468,6 +501,12 @@ int main() if(!boost::container::test::test_emplace, SetOptions>()) return 1; + if(!test_support_for_initialization_list_for>()) + return 1; + + if(!test_support_for_initialization_list_for>()) + return 1; + //////////////////////////////////// // Allocator propagation testing ////////////////////////////////////