Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

Please use vec.h as is and create a file vec.cpp with the methods that are not y

ID: 639658 • Letter: P

Question

Please use vec.h as is and create a file vec.cpp with the methods that

are not yet implemented in vec.h

The method push_back( ) is the one we discussed in class.

We will discuss methods that end with a "const", like size( ) and

operator [ ], next week. For now, please use them as they are.

You will need to add the operator <<( ) in vec.h

Use lab04.cpp as is because it uses the Vec methods as they should

be implemented.

Note that, if you choose NOT to work on the optional part of this

assignment, you need to comment the lines from

    cout << " BEGINNING OF THE OPTIONAL PART... ";

up to, but not including,

    return 0;

This assignment is due on the BlackBoard by midnight one week after it is posted.

Submit only the files FAUID_lab03.cpp FAUID_vec.cpp.

Please see lab04out.txt with the kind of output we expect from your program.

No late assignments.

Please

    - use braces around any block

    - use blocks as we did in our class examples

  - indent your code as we have used indentations in our examples

    - comment your code; do not over comment your code

Penalties:

    o -2 for each missing block

    o -2 for each missing indentation

    o no credit if your cpp file does not compile or does not run

    o some partial credit if your program crashes with different

      input values depending on the problem

Extra credit:

    - three extra points if your program correctly implements

            void erase( int idx, int howmany );

      that appears in vec.h and you use the optional part of lab-04.cpp

end of lab 04.

#include    <iostream>

#include    <iomanip>

using namespace std;

#include    "vec.h"

int main( )

{

    Vec v;                  // v is an object of type Vec

    v.push_back( 10 );      // push 5 ints into v

    v.push_back( 20 );

    v.push_back( 30 );

    v.push_back( 40 );

    v.push_back( 50 );

    v.push_back( 60 );      // try to push one element too many

    cout << "after initializing v: " << v << ' ';

    v.pop_back( );          // remove the last element of v

    cout << "after popping last element of v: " << v << ' ';

    v.erase( 0 );           // erase the first element of v

    cout << "after erasing first element of v: " << v << ' ';

    v.insert( 0, 60 );      // insert value 60 at index 0

    cout << "after inserting 60 at index 0 of v: " << v << ' ';

    v.erase( 1 );           // erase the second element of v

    cout << "after erasing second element of v: " << v << ' ';

                            // erase the last element of v

   v.erase( v.size( ) - 1 );

    cout << "after erasing the last element of v: " << v << ' ';

    v.erase( 0 );           // erase the first element of v

    cout << "after erasing the 1st element of v: " << v << ' ';

    v.insert( 0, 10 );      // insert 10 at position 0

    v.insert( 1, 20 );      // insert 20 at position 1

    v.insert( 3, 40 );      // insert 40 at position 3

    cout << "after inserting three elements in v: " << v << ' ';

    v.insert( 5, 50 );      // try to insert 50 at position 5; invalid!

    cout << "after trying to insert 50 at an invalid loc in v: "

         << v << ' ';

// beginning of the optional part of lab-04

// if you choose NOT to work on the optional part, please comment

// the lines below up to, but not including, return 0;

    cout << " BEGINNING OF THE OPTIONAL PART... ";

    v.erase( 0, 2 );        // erase two elements beginning a loc. 0

    cout << "after erasing two elements starting at 0: " << v << ' ';

    v.erase( 3, 1 );        // erase one elements beginning a loc. 3

    cout << "after attempting to erase one element starting at 3: "

         << v << ' ';      // no changes; position is invalid

    v.erase( 1, 1 );        // erase one elements beginning a loc. 1

    cout << "after erasing one element starting at 1: "

         << v << ' ';

    v.insert( 0, 10 );      // insert 10 at position 0

    v.insert( 1, 20 );      // insert 20 at position 1

    v.insert( 3, 40 );      // insert 40 at position 3

    cout << "after inserting three elements in v: " << v << " ";

    v.erase( 4, 2 );        // invalid erase; no location 4

    cout << "no change in v after invalid erase location: "

         << v << " ";

    v.erase( 3, 4 );        // invalid erase; no 4 elements starting at 3

    cout << "no change in v after invalid erase range: "

         << v << " ";

    v.erase( 0, 4 );        // erase all four elements in v

    cout << "after erasing all elements in v: " << v << " ";

    v.push_back( 10 );      // insert 10 at position 0

    v.push_back( 20 );      // insert 20 at position 1

    v.push_back( 30 );      // insert 30 at position 2

    cout << "after inserting three elements in v: " << v << ' ';

    return 0;

}

NB ---- THIS IS VEC.H

class Vec

{

public:

    Vec( );                 // constructor

    void push_back( int ); // similar to vector

    void pop_back( );       // remove last element in Vec

    void erase( int idx ); // erase element at position idx

    // optional:            // erase howmany elements starting at idx

    void erase( int idx, int howmany );

                            // insert a value at position idx

    void insert( int idx, int value );

    int size( ) const;     // number of elements in array

                            // use operator [ ] as in a vector

    int operator[ ]( int ) const;

private:

    int array[ 5 ];         // local attribute

    int loc;                // local index

};

inline Vec::Vec( )          // constructor

{

    cout << "in Vec::Vec( ) ";

    loc = 0;                // loc refers to the next empty location

}

                            // size of the object

inline int Vec::size( ) const

{

    return loc;

}

                            // return a copy of element at index i

inline int Vec::operator [ ]( int i ) const

{

    if( i >= 0 && i < loc )

    {                       // i is within the range of elements in array

        return array[ i ];

    }

    else

    {

        return -1;          // invalid index; return -1

    }

}

OUTPUT

in Vec::Vec( )

push_back( 10 )   at location 0

push_back( 20 )   at location 1

push_back( 30 )   at location 2

push_back( 40 )   at location 3

push_back( 50 )   at location 4

after initializing v:

   10   20   30   40   50

pop_back( ) at location 4

after popping last element of v:

   10   20   30   40

erase( 0 )

after erasing first element of v:

   20   30   40

insert( 0, 60 )

after inserting 60 at index 0 of v:

   60   20   30   40

erase( 1 )

after erasing second element of v:

   60   30   40

erase( 2 )

after erasing the last element of v:

   60   30

erase( 0 )

after erasing the 1st element of v:

   30

insert( 0, 10 )

insert( 1, 20 )

insert( 3, 40 )

after inserting three elements in v:

   10   20   30   40

insert( 5, 50 )

after trying to insert 50 at an invalid loc in v:

   10   20   30   40

BEGINNING OF THE OPTIONAL PART...

erase( 0, 2 )

after erasing two elements starting at 0:

   30   40

erase( 3, 1 )

after attempting to erase one element starting at 3:

   30   40

erase( 1, 1 )

after erasing one element starting at 1:

   30

insert( 0, 10 )

insert( 1, 20 )

insert( 3, 40 )

after inserting three elements in v:

   10   20   30   40

erase( 4, 2 )

no change in v after invalid erase location:

   10   20   30   40

erase( 3, 4 )

no change in v after invalid erase range:

   10   20   30   40

erase( 0, 4 )

after erasing all elements in v:

push_back( 10 )   at location 0

push_back( 20 )   at location 1

push_back( 30 )   at location 2

after inserting three elements in v:

   10   20   30

Explanation / Answer

main.cpp

#include <iostream>
#include "Vec.h"

using std::cout;
using std::endl;

int main()
{
Vec<int> v;
for (int i = 1; i < 10; ++i)
v.push_back(i);

for(Vec<int>::const_iterator iter = v.begin();
iter != v.end(); ++iter)
cout << *iter << endl;

return 0;
}


Vec.h

#ifndef GUARD_Vec_h
#define GUARD_Vec_h

#include <cstddef>
#include <memory>

template <class T> class Vec {
public:
// member variables
typedef T* iterator;
typedef const T* const_iterator;
typedef std::size_t size_type;
typedef T value_type;
typedef T& reference;
typedef const T& const_reference;

// constructors + destructors
Vec() { create(); }
explicit Vec(size_type n, const T& t = T()) { create(n, t); }
Vec(const Vec& v) { create(v.begin(), v.end()); }
~Vec() { uncreate(); }

// methods
T& operator[](size_type i) { return data[i]; }
const T& operator[](size_type i) const { return data[i]; }

void push_back(const T& t) {
if (avail == limit)
grow();
unchecked_append(t);
}

size_type size() const { return avail - data; }

iterator begin() { return data; }
const_iterator begin() const { return data; }

iterator end() { return avail; }
const_iterator end() const { return avail; }

private:
iterator data;
iterator avail;
iterator limit;

std::allocator<T> alloc;

void create();
void create(size_type, const T&);
void create(const_iterator, const_iterator);

void uncreate();

void grow();
void unchecked_append(const T&);
};

#endif GUARD_Vec_h

Vec.cpp

#include <algorithm>
#include <cstddef>
#include <memory>
#include "Vec.h"

using std::allocator;
using std::max;
using std::uninitialized_copy;
using std::uninitialized_fill;
using std::ptrdiff_t;

template <class T> void Vec<T>::create()
{
data = avail = limit = 0;
}

template <class T> void Vec<T>::create(size_type n, const T& val)
{
data = alloc.allocate(n);
limit = avail = data + n;
uninitialized_fill(data, limit, val);
}

template <class T> void Vec<T>::create(const_iterator i, const_iterator j)
{
data = alloc.allocate(j - i);
limit = avail = uninitialized_copy(i, j, data);
}

template <class T> void Vec<T>::uncreate()
{
if (data) {
iterator it = avail;
while (it != data)
alloc.destroy(--it);

alloc.deallocate(data, limit - data);
}

data = limit = avail = 0;
}

template <class T> void Vec<T>::grow()
{
size_type new_size = max(2 * (limit - data), ptrdiff_t(1));

iterator new_data = alloc.allocate(new_size);
iterator new_avail = uninitialized_copy(data, avail, new_data);

uncreate();

data = new_data;
avail = new_avail;
limit = data + new_size;
}

template <class T> void Vec<T>::unchecked_append(const T& val)
{
alloc.construct(avail++, val);
}