Skip to content

Commit

Permalink
16.53-16.67
Browse files Browse the repository at this point in the history
  • Loading branch information
jzplp committed Aug 10, 2019
1 parent ff19589 commit dc5c211
Show file tree
Hide file tree
Showing 19 changed files with 1,381 additions and 0 deletions.
24 changes: 24 additions & 0 deletions Chapter-16/16.53.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#include<iostream>
#include<string>

template <typename T>
std::ostream & print(std::ostream & os, const T & t)
{
return os << t;
}

template <typename T, typename ... Args>
std::ostream & print(std::ostream & os, const T & t, const Args & ... rest)
{
os << t << ", ";
return print(os, rest...);
}

int main()
{
print(std::cout, 1) << std::endl;
print(std::cout, 1, "123") << std::endl;
print(std::cout, 1, "123", 3.123, std::string("qwert"), -5) << std::endl;
return 0;
}

74 changes: 74 additions & 0 deletions Chapter-16/16.56.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#include<iostream>
#include<string>
#include<sstream>

template <typename T> std::ostream & print(std::ostream & os, const T & t);
template <typename T, typename ... Args> std::ostream & print(std::ostream & os, const T & t, const Args & ... rest);
template <typename T> std::string debug_rep(const T &t);
template <typename T> std::string debug_rep(T * p);
std::string debug_rep(const std::string &s);
std::string debug_rep(char *p);
std::string debug_rep(const char *p);
template <typename ... Args> std::ostream & errorMsg(std::ostream & os, const Args & ... rest);

template <typename T>
std::ostream & print(std::ostream & os, const T & t)
{
return os << t;
}

template <typename T, typename ... Args>
std::ostream & print(std::ostream & os, const T & t, const Args & ... rest)
{
os << t << ", ";
return print(os, rest...);
}

template <typename T>
std::string debug_rep(const T &t)
{
std::ostringstream ret;
ret << t;
return ret.str();
}

template <typename T>
std::string debug_rep(T * p)
{
std::ostringstream ret;
ret << "pointer: " << p;
if(p)
ret << " " << debug_rep(*p);
else
ret << " null pointer";
return ret.str();
}

std::string debug_rep(const std::string &s)
{
return '"' + s + '"';
}

std::string debug_rep(char *p)
{
return debug_rep(std::string(p));
}
std::string debug_rep(const char *p)
{
return debug_rep(std::string(p));
}

template <typename ... Args>
std::ostream & errorMsg(std::ostream & os, const Args & ... rest)
{
return print(os, debug_rep(rest)...);
}

int main()
{
int i = 3;
errorMsg(std::cout, 1, "123", std::string("qwer"), &i) << std::endl;
errorMsg(std::cout, 1) << std::endl;
return 0;
}

198 changes: 198 additions & 0 deletions Chapter-16/16.58/StrVec/StrVec.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
#include<string>
#include<memory>
#include<utility>
#include<algorithm>
#include<utility>
#include<iostream>
#include "StrVec.h"

std::allocator<std::string> StrVec::alloc;

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

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

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

void StrVec::free()
{
if(elements)
{
StrVec * th = this;
std::for_each(elements, first_free, [](std::string &s){ alloc.destroy(&s); } );
alloc.deallocate(elements, cap - elements);
}
}

StrVec::StrVec(const StrVec & s)
{
std::pair<std::string *, std::string *> newdata = alloc_n_copy(s.begin(), s.end());
elements = newdata.first;
first_free = cap = newdata.second;
}

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

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

StrVec & StrVec::operator=(std::initializer_list<std::string> li)
{
std::pair<std::string *, std::string *> data = alloc_n_copy(li.begin(), li.end());
free();
elements = data.first;
first_free = cap = data.second;
return *this;
}

StrVec::StrVec(std::initializer_list<std::string> li)
{
std::pair<std::string *, std::string *> newdata = alloc_n_copy(li.begin(), li.end());
elements = newdata.first;
first_free = cap = newdata.second;
}

StrVec::StrVec(StrVec &&s) noexcept : elements(s.elements), first_free(s.first_free), cap(s.cap)
{
s.elements = s.first_free = s.cap = nullptr;
}

StrVec & StrVec::operator=(StrVec &&rhs) noexcept
{
if(this != &rhs)
{
free();
elements = rhs.elements;
first_free = rhs.first_free;
cap = rhs.cap;
rhs.elements = rhs.first_free = rhs.cap = nullptr;
}
return *this;
}

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

void StrVec::reserve(size_t n)
{
if(n <= capacity())
return;
std::string * newdata = alloc.allocate(n);
std::string * dest = newdata;
std::string * elem = elements;
for(size_t i = 0; i != size(); ++i)
alloc.construct(dest++, std::move(*elem++));
free();
elements = newdata;
first_free = dest;
cap = elements + n;
}

void StrVec::resize(size_t n, const std::string &t)
{
if(n == size())
return;
if(n < size())
{
while(size() != n)
alloc.destroy(--first_free);
return;
}
if(n > capacity())
reserve(n);
while(size() != n)
alloc.construct(first_free++, t);
}

bool operator==(const StrVec &lhs, const StrVec &rhs)
{
if(lhs.size() != rhs.size())
return false;
for(const std::string *p1 = lhs.begin(), *p2 = rhs.begin(); p1 != lhs.end(); ++p1, ++p2)
if(*p1 != *p2)
return false;
return true;
}

bool operator!=(const StrVec &lhs, const StrVec &rhs)
{
return !(lhs == rhs);
}

bool operator<(const StrVec &lhs, const StrVec &rhs)
{
const std::string *p1 = lhs.begin(), *p2 = rhs.begin();
for( ; p1 != lhs.end() && p2 != rhs.end(); ++p1, ++p2)
{
if(*p1 < *p2)
return true;
if(*p1 > *p2)
return false;
}
if(p1 != lhs.end() && p2 == rhs.end())
return false;
if(p1 == lhs.end() && p2 != rhs.end())
return true;
return false;
}

bool operator<=(const StrVec &lhs, const StrVec &rhs)
{
return !(lhs > rhs);
}

bool operator>(const StrVec &lhs, const StrVec &rhs)
{
const std::string *p1 = lhs.begin(), *p2 = rhs.begin();
for( ; p1 != lhs.end() && p2 != rhs.end(); ++p1, ++p2)
{
if(*p1 > *p2)
return true;
if(*p1 < *p2)
return false;
}
if(p1 != lhs.end() && p2 == rhs.end())
return true;
if(p1 == lhs.end() && p2 != rhs.end())
return false;
return false;
}

bool operator>=(const StrVec &lhs, const StrVec &rhs)
{
return !(lhs < rhs);
}

std::string & StrVec::operator[](std::size_t n)
{
return elements[n];
}

const std::string & StrVec::operator[](std::size_t n) const
{
return elements[n];
}
72 changes: 72 additions & 0 deletions Chapter-16/16.58/StrVec/StrVec.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#ifndef STRVEC_H
#define STRVEC_H

#include<string>
#include<memory>
#include<utility>
#include<initializer_list>

class StrVec
{
friend bool operator==(const StrVec &lhs, const StrVec &rhs);
friend bool operator<(const StrVec &lhs, const StrVec &rhs);
friend bool operator>(const StrVec &lhs, const StrVec &rhs);
public:

StrVec() : elements(nullptr), first_free(nullptr), cap(nullptr) { }
StrVec(const StrVec &);
StrVec & operator=(const StrVec &);
~StrVec();
StrVec(std::initializer_list<std::string> li);

StrVec(StrVec &&s) noexcept;
StrVec & operator=(StrVec &&rhs) noexcept;
StrVec & operator=(std::initializer_list<std::string> li);

std::string & operator[](std::size_t n);
const std::string & operator[](std::size_t n) const;

void push_back(const std::string &);
void push_back(std::string &&);
template <typename ... Args> void emplace_back(Args && ... args);

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);
void resize(size_t n, const std::string &t = std::string());
private:

static std::allocator<std::string> alloc;
void chk_n_alloc()
{
if(size() == capacity())
reallocate();
}
std::pair<std::string *, std::string *> alloc_n_copy(const std::string *, const std::string *);
void free();
void reallocate();

std::string * elements;
std::string * first_free;
std::string * cap;
};

bool operator==(const StrVec &lhs, const StrVec &rhs);
bool operator!=(const StrVec &lhs, const StrVec &rhs);
bool operator<(const StrVec &lhs, const StrVec &rhs);
bool operator<=(const StrVec &lhs, const StrVec &rhs);
bool operator>(const StrVec &lhs, const StrVec &rhs);
bool operator>=(const StrVec &lhs, const StrVec &rhs);


template <typename ... Args>
void StrVec::emplace_back(Args && ... args)
{
chk_n_alloc();
alloc.construct(first_free++, std::forward<Args>(args)...);
}

#endif
Loading

0 comments on commit dc5c211

Please sign in to comment.