Boost :: change order of ptr_vector elements

Please can someone tell me how to switch the layout of two elements from the same ptr_vector

without a new heap allocation. That is, I want to do the same as below using std::vector

but with boost::ptr_vector

.

Also, it needs to be done using indices instead of ptr_vector::iterator

.

void switch( vector<int>& V , size_t i , size_t j){
    int a  = V[ j ];
    V[ j ] = V[ i ];
    V[ i ] = a;
}

      

Thanks everyone.

+3


source to share


3 answers


(Untested), I would guess it should be something like:



void switch( ptr_vector<int>& V , size_t i , size_t j){
  auto p = V.replace(i, nullptr); // should get you the value there..
  auto k = V.replace(j, p);       // should get you the value there..
  auto res = V.replace(i, k);
  assert(res == nullptr); // this should be the case...
}

      

+2


source


boost::ptr_vector<T> v;
size_t i = whatever, j = whatever;

// Put this in a separate function
// Do NOT use it as a subexpression or you may (?) forfeit exception safety
v.replace(j, v.replace(i, &v[j]).release()).release();

      



+2


source


You can simply swap the values ​​of the elements:

using std::swap;
swap(v[1], v[2]);

      

This will do exactly what you would expect from the std :: vector case. Here's a demo using a sentinel type to track distributions: Live On Coliru (it doesn't make any new distributions for swap)

Printing

static void* X::operator new(size_t)(4)
X::X(int)(1)
static void* X::operator new(size_t)(4)
X::X(int)(2)
static void* X::operator new(size_t)(4)
X::X(int)(3)
static void* X::operator new(size_t)(4)
X::X(int)(4)
X[1] X[2] X[3] X[4] 
===============================
swapping v[1] and v[2]:
X::X(X&&)(X[2])
X& X::operator=(X&&)(X[3])
X& X::operator=(X&&)(X[2])
X::~X()

===============================
X[1] X[3] X[2] X[4] X::~X()
static void X::operator delete(void*)
X::~X()
static void X::operator delete(void*)
X::~X()
static void X::operator delete(void*)
X::~X()
static void X::operator delete(void*)

      

Complete program

#include <boost/ptr_container/ptr_vector.hpp>

struct X {
    X(int i) : _i(i)         { std::cout << __PRETTY_FUNCTION__ << "(" << i << ")" << "\n"; }
    X(X && x) : _i(x._i)     { std::cout << __PRETTY_FUNCTION__ << "(" << x << ")" << "\n"; }
    X(X const& x) : _i(x._i) { std::cout << __PRETTY_FUNCTION__ << "(" << x << ")" << "\n"; }
    ~X()                     { std::cout << __PRETTY_FUNCTION__ << "\n"; }

    void* operator new(size_t n) {
         std::cout << __PRETTY_FUNCTION__ << "(" << n << ")" << "\n";
         return ::operator new(n);
    }

    void operator delete(void* px) {
         std::cout << __PRETTY_FUNCTION__ << "\n";
         return ::operator delete(static_cast<X*>(px));
    }

    X& operator=(X const& x) { 
        _i = x._i;
        std::cout << __PRETTY_FUNCTION__ << "(" << x << ")" << "\n"; 
        return *this;
    }

    X& operator=(X && x) { 
        _i = x._i;
        std::cout << __PRETTY_FUNCTION__ << "(" << x << ")" << "\n"; 
        return *this;
    }

    friend std::ostream& operator<<(std::ostream& os, X const& x) {
        return os << "X[" << x._i << "]";
    }
    private: int _i;
};

int main()
{
    boost::ptr_vector<X> v;
    v.push_back(new X(1));
    v.push_back(new X(2));
    v.push_back(new X(3));
    v.push_back(new X(4));

    for (auto& p : v)
        std::cout << p << " ";

    std::cout << "\n===============================\nswapping v[1] and v[2]:\n";

    using std::swap;
    swap(v[1], v[2]);

    std::cout << "\n===============================\n";

    for (auto& p : v)
        std::cout << p << " ";
}

      

0


source







All Articles