std::list<item> visitable<inventory>::remove_items_with( const std::function<bool( const item &e )> &filter, int count ) { auto inv = static_cast<inventory *>( this ); std::list<item> res; if( count <= 0 ) { return res; // nothing to do } for( auto stack = inv->items.begin(); stack != inv->items.end() && count > 0; ) { std::list<item> &istack = *stack; const auto original_invlet = istack.front().invlet; for( auto istack_iter = istack.begin(); istack_iter != istack.end() && count > 0; ) { if( filter( *istack_iter ) ) { count--; res.splice( res.end(), istack, istack_iter++ ); // The non-first items of a stack may have different invlets, the code // in inventory only ever checks the invlet of the first item. This // ensures that the first item of a stack always has the same invlet, even // after the orignal first item was removed. if( istack_iter == istack.begin() && istack_iter != istack.end() ) { istack_iter->invlet = original_invlet; } } else { remove_internal( filter, *istack_iter, count, res ); ++istack_iter; } } if( istack.empty() ) { stack = inv->items.erase( stack ); } else { ++stack; } } return res; }
std::list<item> visitable<vehicle_cursor>::remove_items_with( const std::function<bool( const item &e )> &filter, int count ) { auto cur = static_cast<vehicle_cursor *>( this ); std::list<item> res; if( count <= 0 ) { return res; // nothing to do } vehicle_part& part = cur->veh.parts[ cur->part ]; for( auto iter = part.items.begin(); iter != part.items.end(); ) { if( filter( *iter ) ) { // check for presence in the active items cache if( cur->veh.active_items.has( iter, part.mount ) ) { cur->veh.active_items.remove( iter, part.mount ); } res.splice( res.end(), part.items, iter++ ); if( --count == 0 ) { return res; } } else { remove_internal( filter, *iter, count, std::back_inserter( res ) ); if( count == 0 ) { return res; } ++iter; } } if( !res.empty() ) { // if we removed any items then invalidate the cached mass cur->veh.invalidate_mass(); } return res; }
inline void HeapRegionSet::remove(HeapRegion* hr) { hrl_assert_mt_safety_ok(this); // remove_internal() will verify the region. remove_internal(hr); }