Skip to content

Commit

Permalink
added ex13_39
Browse files Browse the repository at this point in the history
  • Loading branch information
pezy committed Feb 3, 2015
1 parent a6f4515 commit 828dc14
Show file tree
Hide file tree
Showing 3 changed files with 152 additions and 1 deletion.
4 changes: 3 additions & 1 deletion ch13/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -223,4 +223,6 @@ some existing `Folders` will out of sync with the `Message` after assignment.
The copy and swap is an elegant way when working with dynamicly allocated memory. In the Message class ,noing is allocated dynamically. Thus using this idiom makes no sense and will make it more complicated to implement due to the pointers that point back.
@pezy
In this case, `swap` function is special. It will be clear two `Message`'s folders , then swap members, and added themselves to each folders. But, `Message` assignment operator just clear itself, and copy the members, and added itself to each folders. The `rhs` don't need to clear and add to folders. So, if using copy and swap to define, it will be very inefficiency.
In this case, `swap` function is special. It will be clear two `Message`'s folders , then swap members, and added themselves to each folders. But, `Message` assignment operator just clear itself, and copy the members, and added itself to each folders. The `rhs` don't need to clear and add to folders. So, if using copy and swap to define, it will be very inefficiency.
## Exercise 13.39 [hpp](ex13_39.h) | [cpp](ex13_39.cpp)
98 changes: 98 additions & 0 deletions ch13/ex13_39.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
//
// ex13_39.cpp
// Exercise 13.39
//
// Created by pezy on 2/3/15.
// Copyright (c) 2015 pezy. All rights reserved.
//
// Write your own version of StrVec, including versions of
// reserve, capacity (9.4, p. 356), and resize (9.3.5, p. 352).
//

#include "StrVec.h"

void StrVec::push_back(const std::string &s)
{
chk_n_alloc();
alloc.construct(first_free++, s);
}

std::pair<std::string*, std::string*>
StrVec::alloc_n_copy(const std::string *b, const std::string *e)
{
auto data = alloc.allocate(e-b);
return { data, std::uninitialized_copy(b, e, data) };
}

void StrVec::free()
{
if (elements) {
for (auto p = first_free; p != elements;)
alloc.destroy(--p);
alloc.deallocate(elements, cap - elements);
}
}

StrVec::StrVec(const StrVec &rhs)
{
auto newdata = alloc_n_copy(rhs.begin(), rhs.end());
elements = newdata.first;
first_free = cap = newdata.second;
}

StrVec::~StrVec()
{
free();
}

StrVec& StrVec::operator = (const StrVec &rhs)
{
auto data = alloc_n_copy(rhs.begin(), rhs.end());
free();
elements = data.first;
first_free = cap = data.second;
return *this;
}

void StrVec::alloc_n_move(size_t new_cap)
{
auto newdata = alloc.allocate(new_cap);
auto dest = newdata;
auto elem = elements;
for (size_t i = 0; i != size(); ++i)
alloc.construct(dest++, std::move(*elem++));
free();
elements = newdata;
first_free = dest;
cap = elements + new_cap;
}

void StrVec::reallocate()
{
auto newcapacity = size() ? 2 * size() : 1;
alloc_n_move(newcapacity);
}

void StrVec::reserve(size_t new_cap)
{
if (new_cap <= capacity()) return;
alloc_n_move(new_cap);
}

void StrVec::resize(size_t count)
{
resize(count, std::string());
}

void StrVec::resize(size_t count, const std::string &s)
{
if (count > size()) {
if (count > capacity()) reserve(count * 2);
for (size_t i = size(); i != count; ++i)
alloc.construct(first_free++, s);
}
else if (count < size()) {
while (first_free != elements + count)
alloc.destroy(--first_free);
}
}
51 changes: 51 additions & 0 deletions ch13/ex13_39.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
//
// ex13_39.h
// Exercise 13.39
//
// Created by pezy on 2/3/15.
// Copyright (c) 2015 pezy. All rights reserved.
//
// Write your own version of StrVec, including versions of
// reserve, capacity (9.4, p. 356), and resize (9.3.5, p. 352).
//

#ifndef CP5_EX_13_39_H_
#define CP5_EX_13_39_H_

#include <memory>
#include <string>

class StrVec
{
public:
StrVec() : elements(nullptr), first_free(nullptr), cap(nullptr) {}
StrVec(const StrVec&);
StrVec& operator=(const StrVec&);
~StrVec();

void push_back(const std::string&);
size_t size() const { return first_free - elements; }
size_t capacity() const { return cap - elements; }
std::string *begin() const { return elements; }
std::string *end() const { return first_free; }

void reserve(size_t new_cap);
void resize(size_t count);
void resize(size_t count, const std::string&);

private:
std::pair<std::string*, std::string*> alloc_n_copy(const std::string*, const std::string*);
void free();
void chk_n_alloc() { if (size() == capacity()) reallocate(); }
void reallocate();
void alloc_n_move(size_t new_cap);

private:
std::string *elements;
std::string *first_free;
std::string *cap;
std::allocator<std::string> alloc;
};

#endif

0 comments on commit 828dc14

Please sign in to comment.