7 changes: 6 additions & 1 deletion include/boost/multi_index/sequenced_index.hpp
@@ -1,4 +1,4 @@
/* Copyright 2003-2015 Joaquin M Lopez Munoz.
/* Copyright 2003-2017 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)
Expand Down Expand Up @@ -771,6 +771,11 @@ class sequenced_index:
return super::modify_rollback_(x);
}

bool check_rollback_(node_type* x)const
{
return super::check_rollback_(x);
}

#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
/* serialization */

Expand Down
22 changes: 19 additions & 3 deletions include/boost/multi_index_container.hpp
@@ -1,6 +1,6 @@
/* Multiply indexed container.
*
* Copyright 2003-2014 Joaquin M Lopez Munoz.
* Copyright 2003-2017 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)
Expand Down Expand Up @@ -810,7 +810,14 @@ class multi_index_container:
template<typename Modifier>
bool modify_(Modifier& mod,node_type* x)
{
mod(const_cast<value_type&>(x->value()));
BOOST_TRY{
mod(const_cast<value_type&>(x->value()));
}
BOOST_CATCH(...){
this->erase_(x);
BOOST_RETHROW;
}
BOOST_CATCH_END

BOOST_TRY{
if(!super::modify_(x)){
Expand All @@ -831,7 +838,14 @@ class multi_index_container:
template<typename Modifier,typename Rollback>
bool modify_(Modifier& mod,Rollback& back_,node_type* x)
{
mod(const_cast<value_type&>(x->value()));
BOOST_TRY{
mod(const_cast<value_type&>(x->value()));
}
BOOST_CATCH(...){
this->erase_(x);
BOOST_RETHROW;
}
BOOST_CATCH_END

bool b;
BOOST_TRY{
Expand All @@ -840,6 +854,7 @@ class multi_index_container:
BOOST_CATCH(...){
BOOST_TRY{
back_(const_cast<value_type&>(x->value()));
if(!super::check_rollback_(x))this->erase_(x);
BOOST_RETHROW;
}
BOOST_CATCH(...){
Expand All @@ -853,6 +868,7 @@ class multi_index_container:
BOOST_TRY{
if(!b){
back_(const_cast<value_type&>(x->value()));
if(!super::check_rollback_(x))this->erase_(x);
return false;
}
else return true;
Expand Down
110 changes: 97 additions & 13 deletions test/test_modifiers.cpp
@@ -1,6 +1,6 @@
/* Boost.MultiIndex test for modifier memfuns.
*
* Copyright 2003-2014 Joaquin M Lopez Munoz.
* Copyright 2003-2017 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)
Expand Down Expand Up @@ -136,6 +136,26 @@ struct tempvalue_iterator:
int n;
};

struct change_int
{
change_int(int n):n(n){}

void operator()(int& x)const{x=n;}

int n;
};

#if !(defined BOOST_NO_EXCEPTIONS)
struct change_int_and_throw
{
change_int_and_throw(int n):n(n){}

void operator()(int& x)const{x=n;throw 0;}

int n;
};
#endif

void test_modifiers()
{
employee_set es;
Expand Down Expand Up @@ -480,17 +500,81 @@ void test_modifiers()
* https://svn.boost.org/trac/boost/ticket/9665
*/

multi_index_container<
int,
indexed_by<hashed_unique<identity<int> > >
> hc;
hc.insert(tempvalue_iterator(0),tempvalue_iterator(10));
BOOST_TEST(hc.size()==10);
{
multi_index_container<
int,
indexed_by<hashed_unique<identity<int> > >
> hc;
hc.insert(tempvalue_iterator(0),tempvalue_iterator(10));
BOOST_TEST(hc.size()==10);

multi_index_container<
int,
indexed_by<ordered_unique<identity<int> > >
> oc;
oc.insert(tempvalue_iterator(0),tempvalue_iterator(10));
BOOST_TEST(oc.size()==10);
}

multi_index_container<
int,
indexed_by<ordered_unique<identity<int> > >
> oc;
oc.insert(tempvalue_iterator(0),tempvalue_iterator(10));
BOOST_TEST(oc.size()==10);
/* testcases for https://svn.boost.org/trac10/ticket/12542 */

{
multi_index_container<
int,
indexed_by<
ordered_unique<identity<int> >,
hashed_unique<identity<int> >
>
> ohc;

#if !(defined BOOST_NO_EXCEPTIONS)
ohc.insert(0);
ohc.insert(1);

try{
ohc.modify_key(ohc.begin(),change_int_and_throw(1));
}
catch(int){}
BOOST_TEST(ohc.size()==1);
ohc.clear();

ohc.insert(0);
ohc.insert(1);

try{
ohc.modify_key(ohc.begin(),change_int_and_throw(1),change_int(0));
}
catch(int){}
BOOST_TEST(ohc.size()==1);
ohc.clear();

ohc.insert(0);
ohc.insert(1);

try{
ohc.modify_key(
ohc.begin(),change_int_and_throw(1),change_int_and_throw(0));
}
catch(int){}
BOOST_TEST(ohc.size()==1);
ohc.clear();

ohc.insert(0);
ohc.insert(1);

try{
ohc.modify_key(ohc.begin(),change_int(1),change_int_and_throw(0));
}
catch(int){}
BOOST_TEST(ohc.size()==1);
ohc.clear();
#endif

ohc.insert(0);
ohc.insert(1);

ohc.modify_key(ohc.begin(),change_int(1),change_int(1));
BOOST_TEST(ohc.size()==1);
ohc.clear();
}
}