提交 e9156b43 编写于 作者: J jzplp

14.13-14.19

上级 73363b60
#include <iostream>
#include <string>
#include "Sales_data.h"
Sales_data & Sales_data::operator+=(const Sales_data & sa)
{
amount += sa.amount;
totalPrice += sa.totalPrice;
return *this;
}
inline double Sales_data::avg_price() const
{
if(amount)
return totalPrice / amount;
return 0;
}
Sales_data operator+(const Sales_data & sa, const Sales_data & sb)
{
Sales_data sum = sa;
sum += sb;
return sum;
}
std::istream & operator>>(std::istream & is, Sales_data & sa)
{
double price = 0;
is >> sa.ISBN >> sa.amount >> price;
if(is)
sa.totalPrice = price * sa.amount;
else
sa = Sales_data();
return is;
}
std::ostream & operator<<(std::ostream & os, const Sales_data & sa)
{
os << sa.isbn() << " " << sa.amount << " " << sa.totalPrice << " " << sa.avg_price();
return os;
}
bool operator==(const Sales_data &lhs, const Sales_data &rhs)
{
return lhs.isbn() == rhs.isbn() && lhs.totalPrice == rhs.totalPrice && lhs.amount == rhs.amount;
}
bool operator!=(const Sales_data &lhs, const Sales_data &rhs)
{
return !(lhs == rhs);
}
#ifndef SALES_DATA_H
#define SALES_DATA_H
#include <iostream>
#include<string>
struct Sales_data;
Sales_data operator+(const Sales_data & sa, const Sales_data & sb);
std::istream & operator>>(std::istream & is, Sales_data & sa);
std::ostream & operator<<(std::ostream & os, const Sales_data & sa);
bool operator==(const Sales_data &lhs, const Sales_data &rhs);
bool operator!=(const Sales_data &lhs, const Sales_data &rhs);
class Sales_data
{
friend Sales_data operator+(const Sales_data & sa, const Sales_data & sb);
friend std::istream & operator>>(std::istream & is, Sales_data & sa);
friend std::ostream & operator<<(std::ostream & os, const Sales_data & sa);
friend bool operator==(const Sales_data &lhs, const Sales_data &rhs);
public:
Sales_data() = default;
Sales_data(const std::string &s) : ISBN(s) { }
Sales_data(const std::string &s, int a, double t) : ISBN(s), amount(a), totalPrice(t * a) { }
Sales_data(std::istream &is)
{
is >> *this;
}
std::string isbn() const
{
return ISBN;
}
Sales_data & operator+=(const Sales_data & sa);
private:
std::string ISBN;
double totalPrice = 0.0;
int amount = 0;
inline double avg_price() const;
};
#endif
#include <iostream>
#include "Sales_data.h"
int main()
{
Sales_data a(std::cin);
Sales_data b(std::cin);
std::cout << (a == b) << std::endl;
return 0;
}
#include<memory>
#include<vector>
#include<string>
#include<stdexcept>
#include "StrBlob.h"
StrBlob::StrBlob() : data(std::make_shared<std::vector<std::string>>()) { }
StrBlob::StrBlob(std::initializer_list<std::string> li) : data(std::make_shared<std::vector<std::string>>(li)) { }
StrBlob::StrBlob(const StrBlob &sb) : data(std::make_shared<std::vector<std::string>>(*(sb.data))) { }
void StrBlob::push_back(std::string &&t)
{
data->push_back(std::move(t));
}
StrBlob & StrBlob::operator=(const StrBlob &sb)
{
data = std::make_shared<std::vector<std::string>>(*(sb.data));
return *this;
}
void StrBlob::check(size_type i, const std::string & msg) const
{
if(i >= data->size())
throw std::out_of_range(msg);
}
void StrBlob::pop_back()
{
check(0, "pop_back on empty StrBlob");
data->pop_back();
}
const std::string & StrBlob::front() const
{
check(0, "front on empty StrBlob");
return data->front();
}
std::string & StrBlob::front()
{
check(0, "front on empty StrBlob");
return data->front();
}
const std::string & StrBlob::back() const
{
check(0, "back on empty StrBlob");
return data->back();
}
std::string & StrBlob::back()
{
check(0, "back on empty StrBlob");
return data->back();
}
StrBlobPtr StrBlob::begin()
{
return StrBlobPtr(*this);
}
StrBlobPtr StrBlob::end()
{
return StrBlobPtr(*this, data->size());
}
ConstStrBlobPtr StrBlob::cbegin() const
{
return ConstStrBlobPtr(*this);
}
ConstStrBlobPtr StrBlob::cend() const
{
return ConstStrBlobPtr(*this, data->size());
}
std::shared_ptr<std::vector<std::string>> StrBlobPtr::check(std::size_t i, const std::string & msg) const
{
std::shared_ptr<std::vector<std::string>> ret = wptr.lock();
if(!ret)
throw std::runtime_error("unbound StrBlobPtr");
if(i >= ret->size())
throw std::out_of_range(msg);
return ret;
}
std::string & StrBlobPtr::deref() const
{
std::shared_ptr<std::vector<std::string>> p = check(curr, "dereference past end");
return (*p)[curr];
}
StrBlobPtr & StrBlobPtr::incr()
{
check(curr, "increment past end of StrBlobPtr");
++curr;
return *this;
}
StrBlobPtr & StrBlobPtr::add(StrBlob::size_type num)
{
check(curr + num, "increment past end of StrBlobPtr");
curr += num;
return *this;
}
bool compare(const StrBlobPtr &p1, const StrBlobPtr &p2)
{
if(p1.wptr.lock() == p2.wptr.lock() && p1.curr == p2.curr)
return true;
return false;
}
std::shared_ptr<std::vector<std::string>> ConstStrBlobPtr::check(std::size_t i, const std::string & msg) const
{
std::shared_ptr<std::vector<std::string>> ret = wptr.lock();
if(!ret)
throw std::runtime_error("unbound StrBlobPtr");
if(i >= ret->size())
throw std::out_of_range(msg);
return ret;
}
std::string & ConstStrBlobPtr::deref() const
{
std::shared_ptr<std::vector<std::string>> p = check(curr, "dereference past end");
return (*p)[curr];
}
ConstStrBlobPtr & ConstStrBlobPtr::incr()
{
check(curr, "increment past end of StrBlobPtr");
++curr;
return *this;
}
bool compare(const ConstStrBlobPtr &p1, const ConstStrBlobPtr &p2)
{
if(p1.wptr.lock() == p2.wptr.lock() && p1.curr == p2.curr)
return true;
return false;
}
bool operator==(const StrBlob &lhs, const StrBlob &rhs)
{
if(lhs.size() != rhs.size())
return false;
for(ConstStrBlobPtr p1 = lhs.cbegin(), p2 = rhs.cbegin(); p1 != lhs.cend(); p1.incr(), p2.incr())
if(p1.deref() != p2.deref())
return false;
return true;
}
bool operator==(const StrBlobPtr &lhs, const StrBlobPtr &rhs)
{
return (lhs.wptr.lock() == rhs.wptr.lock() && lhs.curr == rhs.curr);
}
bool operator==(const ConstStrBlobPtr &lhs, const ConstStrBlobPtr &rhs)
{
return (lhs.wptr.lock() == rhs.wptr.lock() && lhs.curr == rhs.curr);
}
bool operator!=(const StrBlob &lhs, const StrBlob &rhs)
{
return !(lhs == rhs);
}
bool operator!=(const StrBlobPtr &lhs, const StrBlobPtr &rhs)
{
return !(lhs == rhs);
}
bool operator!=(const ConstStrBlobPtr &lhs, const ConstStrBlobPtr &rhs)
{
return !(lhs == rhs);
}
#ifndef STRBLOB_H
#define STRBLOB_H
#include<vector>
#include<string>
#include<initializer_list>
#include<utility>
#include<memory>
class StrBlobPtr;
class ConstStrBlobPtr;
class StrBlob
{
friend class StrBlobPtr;
friend class ConstStrBlobPtr;
friend bool operator==(const StrBlob &lhs, const StrBlob &rhs);
friend bool operator!=(const StrBlob &lhs, const StrBlob &rhs);
public:
typedef std::vector<std::string>::size_type size_type;
StrBlob();
StrBlob(std::initializer_list<std::string> li);
StrBlob(const StrBlob &sb);
StrBlob & operator=(const StrBlob &sb);
inline size_type size() const { return data->size(); }
bool empty() const { return data->empty(); }
void push_back(const std::string &t) { data->push_back(t); }
void push_back(std::string &&t);
void pop_back();
const std::string & front() const;
std::string & front();
const std::string & back() const;
std::string & back();
StrBlobPtr begin();
StrBlobPtr end();
ConstStrBlobPtr cbegin() const;
ConstStrBlobPtr cend() const;
private:
std::shared_ptr<std::vector<std::string>> data;
void check(size_type i, const std::string & msg) const;
};
class StrBlobPtr
{
friend bool compare(const StrBlobPtr &p1, const StrBlobPtr &p2);
friend bool operator==(const StrBlobPtr &lhs, const StrBlobPtr &rhs);
friend bool operator!=(const StrBlobPtr &lhs, const StrBlobPtr &rhs);
public:
StrBlobPtr() : curr(0) { }
StrBlobPtr(StrBlob &a, std::size_t sz = 0) : wptr(a.data), curr(sz) { }
std::string & deref() const;
StrBlobPtr & incr();
StrBlobPtr & add(StrBlob::size_type num);
private:
std::shared_ptr<std::vector<std::string>> check(std::size_t , const std::string &) const;
std::weak_ptr<std::vector<std::string>> wptr;
std::size_t curr;
};
class ConstStrBlobPtr
{
friend bool compare(const ConstStrBlobPtr &p1, const ConstStrBlobPtr &p2);
friend bool operator==(const ConstStrBlobPtr &lhs, const ConstStrBlobPtr &rhs);
friend bool operator!=(const ConstStrBlobPtr &lhs, const ConstStrBlobPtr &rhs);
public:
ConstStrBlobPtr() : curr(0) { }
ConstStrBlobPtr(const StrBlob &a, std::size_t sz = 0) : wptr(a.data), curr(sz) { }
std::string & deref() const;
ConstStrBlobPtr & incr();
private:
std::shared_ptr<std::vector<std::string>> check(std::size_t , const std::string &) const;
std::weak_ptr<std::vector<std::string>> wptr;
std::size_t curr;
};
bool operator==(const StrBlob &lhs, const StrBlob &rhs);
bool operator==(const StrBlobPtr &lhs, const StrBlobPtr &rhs);
bool operator==(const ConstStrBlobPtr &lhs, const ConstStrBlobPtr &rhs);
bool operator!=(const StrBlob &lhs, const StrBlob &rhs);
bool operator!=(const StrBlobPtr &lhs, const StrBlobPtr &rhs);
bool operator!=(const ConstStrBlobPtr &lhs, const ConstStrBlobPtr &rhs);
#endif
#include<iostream>
#include<string>
#include<utility>
#include "StrBlob.h"
int main()
{
StrBlob b1;
std::string s;
while(std::cin >> s)
b1.push_back(std::move(s));
StrBlob b2 = b1;
b2 = b2;
for(ConstStrBlobPtr p= b2.cbegin(); p != b2.cend(); p.incr())
std::cout << p.deref() << " ";
std::cout << std::endl;
std::cout << (b1 == b2) << std::endl;
return 0;
}
#include<string>
#include<memory>
#include<utility>
#include<algorithm>
#include<utility>
#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(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);
}
#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);
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;
void push_back(const std::string &);
void push_back(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);
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);
#endif