14.2:
#pragma once #includeusing namespace std; #include #include class Sales_data { friend istream& read(istream& is, Sales_data& item); friend ostream& print(ostream& os, const Sales_data& item); friend Sales_data add(const Sales_data& s1, const Sales_data& s2); friend istream& operator>>(istream& , Sales_data&); friend ostream& operator<<(ostream& , const Sales_data&); friend Sales_data operator+(const Sales_data& s1, const Sales_data& s2); public: Sales_data() = default; Sales_data(const string& s) :bookNo(s) {}; Sales_data(const string& s, unsigned n, double p) :bookNo(s), unit_sold(n), revenue(n* p) {}; Sales_data(istream& is) { read(cin, *this); } Sales_data& operator+=(const Sales_data& s); Sales_data& combine(const Sales_data& rhs); string isbn()const { return this->bookNo; } private: inline double avg_price()const; string bookNo; unsigned unit_sold = 0; double revenue = 0.0; }; Sales_data& Sales_data::combine(const Sales_data& rhs) { this->unit_sold += rhs.unit_sold; this->revenue += rhs.revenue; return *this; } Sales_data add(const Sales_data& s1, const Sales_data& s2) { Sales_data temp = s1; temp.combine(s2); return temp; } istream& read(istream& is, Sales_data& item) { double price = 0; is >> item.bookNo >> item.unit_sold >> price; item.revenue = item.unit_sold * price; return is; } ostream& print(ostream& os, const Sales_data& item) { os << item.bookNo << " " << item.unit_sold << " " << item.revenue; return os; } inline double Sales_data::avg_price()const { return unit_sold ? revenue / unit_sold : 0; } istream& operator>>(istream& in, Sales_data& sd) { double price = 0; in >> sd.bookNo >> sd.unit_sold >> price; if (in) { sd.revenue = sd.unit_sold * price; } else { sd = Sales_data(); } return in; } ostream& operator<<(ostream& out, const Sales_data& item) { out << item.bookNo << " " << item.unit_sold << " " << item.revenue << " " << item.avg_price(); return out; } Sales_data operator+(const Sales_data& s1, const Sales_data & s2) { Sales_data temp = s1; temp.unit_sold += s2.unit_sold; temp.revenue += s2.revenue; return temp; } Sales_data& Sales_data::operator+=(const Sales_data& s) { this->unit_sold += s.unit_sold; this->revenue += s.revenue; return *this; }
14.7:
String.h:
#pragma once #includeusing namespace std; #include class String { friend ostream& operator<< (ostream& os, const String& s); public: String():String("") {} String(const String&); String(const char*); String& operator=(const String&); String(String&&)noexcept; String& operator=(String&&)noexcept; ~String(); const char* c_str() const { return elements; } size_t size() const { return end - elements; } size_t length() const { return end - elements - 1; } private: pair alloc_n_copy(const char*, const char*); void range_initializer(const char*, const char*); void free(); char* elements; char* end; allocator alloc; }; ostream& operator<< (ostream& os, const String& s);
String.cpp:
#include"string.h" pairString::alloc_n_copy(const char*b, const char*e) { auto str = alloc.allocate(e - b); return { str,uninitialized_copy(b,e,str) }; } void String::range_initializer(const char*b, const char*e) { auto newstr = alloc_n_copy(b, e); elements = newstr.first; end = newstr.second; } String::String(const char*s) { char* s1 = const_cast (s); while (*s1) { ++s1; } range_initializer(s, ++s1); } String::String(const String&rhs) { range_initializer(rhs.elements, rhs.end); cout << "copy constructor" << endl; } void String::free() { if (elements) { for_each(elements, end, [this](char& c) {alloc.destroy(&c); }); alloc.deallocate(elements, end - elements); } } String::~String() { free(); } String& String::operator=(const String&rhs) { auto newstr = alloc_n_copy(rhs.elements, rhs.end); free(); elements = newstr.first; end = newstr.second; cout << "copy assignment" << endl; return *this; } String::String(String&&s)noexcept:elements(s.elements),end(s.end) { s.elements = s.end = nullptr; } String& String::operator=(String&&s)noexcept { if (this != &s) { free(); elements = s.elements; end = s.end; s.elements = s.end = nullptr; } return *this; } ostream& operator<< (ostream& os, const String& s) { char* c = const_cast (s.c_str()); while (*c) { os << *c++; } return os; }
14.13:
#pragma once #includeusing namespace std; #include #include class Sales_data { friend istream& read(istream& is, Sales_data& item); friend ostream& print(ostream& os, const Sales_data& item); friend Sales_data add(const Sales_data& s1, const Sales_data& s2); friend istream& operator>>(istream& , Sales_data&); friend ostream& operator<<(ostream& , const Sales_data&); friend Sales_data operator+(const Sales_data& s1, const Sales_data& s2); friend Sales_data operator-(const Sales_data& s1, const Sales_data& s2); public: Sales_data() = default; Sales_data(const string& s) :bookNo(s) {}; Sales_data(const string& s, unsigned n, double p) :bookNo(s), unit_sold(n), revenue(n* p) {}; Sales_data(istream& is) { read(cin, *this); } Sales_data& operator+=(const Sales_data& s); Sales_data& operator-=(const Sales_data& s); Sales_data& combine(const Sales_data& rhs); string isbn()const { return this->bookNo; } private: inline double avg_price()const; string bookNo; unsigned unit_sold = 0; double revenue = 0.0; }; Sales_data& Sales_data::combine(const Sales_data& rhs) { this->unit_sold += rhs.unit_sold; this->revenue += rhs.revenue; return *this; } Sales_data add(const Sales_data& s1, const Sales_data& s2) { Sales_data temp = s1; temp.combine(s2); return temp; } istream& read(istream& is, Sales_data& item) { double price = 0; is >> item.bookNo >> item.unit_sold >> price; item.revenue = item.unit_sold * price; return is; } ostream& print(ostream& os, const Sales_data& item) { os << item.bookNo << " " << item.unit_sold << " " << item.revenue; return os; } inline double Sales_data::avg_price()const { return unit_sold ? revenue / unit_sold : 0; } istream& operator>>(istream& in, Sales_data& sd) { double price = 0; in >> sd.bookNo >> sd.unit_sold >> price; if (in) { sd.revenue = sd.unit_sold * price; } else { sd = Sales_data(); } return in; } ostream& operator<<(ostream& out, const Sales_data& item) { out << item.bookNo << " " << item.unit_sold << " " << item.revenue << " " << item.avg_price(); return out; } Sales_data operator+(const Sales_data& s1, const Sales_data & s2) { Sales_data temp = s1; temp.unit_sold += s2.unit_sold; temp.revenue += s2.revenue; return temp; } Sales_data& Sales_data::operator+=(const Sales_data& s) { this->unit_sold += s.unit_sold; this->revenue += s.revenue; return *this; } Sales_data operator-(const Sales_data& s1, const Sales_data& s2) { Sales_data temp = s1; temp -= s2; return temp; } Sales_data& Sales_data::operator-=(const Sales_data& s) { this->unit_sold -= s.unit_sold; this->revenue -= s.revenue; return *this; }
14.16:
string.h:
#pragma once #includeusing namespace std; #include class String { friend ostream& operator<< (ostream& os, const String& s); friend bool operator==(const String& s1, const String& s2); friend bool operator!=(const String& s1, const String& s2); public: String():String("") {} String(const String&); String(const char*); String& operator=(const String&); String(String&&)noexcept; String& operator=(String&&)noexcept; ~String(); const char* c_str() const { return elements; } size_t size() const { return end - elements; } size_t length() const { return end - elements - 1; } private: pair alloc_n_copy(const char*, const char*); void range_initializer(const char*, const char*); void free(); char* elements; char* end; allocator alloc; }; ostream& operator<< (ostream& os, const String& s); bool operator==(const String& s1, const String& s2); bool operator!=(const String& s1, const String& s2);
string.cpp:
#include"string.h" pairString::alloc_n_copy(const char*b, const char*e) { auto str = alloc.allocate(e - b); return { str,uninitialized_copy(b,e,str) }; } void String::range_initializer(const char*b, const char*e) { auto newstr = alloc_n_copy(b, e); elements = newstr.first; end = newstr.second; } String::String(const char*s) { char* s1 = const_cast (s); while (*s1) { ++s1; } range_initializer(s, ++s1); } String::String(const String&rhs) { range_initializer(rhs.elements, rhs.end); cout << "copy constructor" << endl; } void String::free() { if (elements) { for_each(elements, end, [this](char& c) {alloc.destroy(&c); }); alloc.deallocate(elements, end - elements); } } String::~String() { free(); } String& String::operator=(const String&rhs) { auto newstr = alloc_n_copy(rhs.elements, rhs.end); free(); elements = newstr.first; end = newstr.second; cout << "copy assignment" << endl; return *this; } String::String(String&&s)noexcept:elements(s.elements),end(s.end) { s.elements = s.end = nullptr; } String& String::operator=(String&&s)noexcept { if (this != &s) { free(); elements = s.elements; end = s.end; s.elements = s.end = nullptr; } return *this; } ostream& operator<< (ostream& os, const String& s) { char* c = const_cast (s.c_str()); while (*c) { os << *c++; } return os; } bool operator==(const String& s1, const String& s2) { return s1.size() == s2.size() && equal(s1.elements, s1.end, s2.elements); } bool operator!=(const String& s1, const String& s2) { return !(s1 == s2); }
14.18:
string.h:
#pragma once #includeusing namespace std; #include class String { friend ostream& operator<< (ostream& os, const String& s); friend bool operator==(const String& s1, const String& s2); friend bool operator!=(const String& s1, const String& s2); friend bool operator< (const String& s1, const String& s2); friend bool operator<= (const String& s1, const String& s2); friend bool operator> (const String& s1, const String& s2); friend bool operator>= (const String& s1, const String& s2); public: String():String("") {} String(const String&); String(const char*); String& operator=(const String&); String(String&&)noexcept; String& operator=(String&&)noexcept; ~String(); const char* c_str() const { return elements; } size_t size() const { return end - elements; } size_t length() const { return end - elements - 1; } private: pair alloc_n_copy(const char*, const char*); void range_initializer(const char*, const char*); void free(); char* elements; char* end; allocator alloc; }; ostream& operator<< (ostream& os, const String& s); bool operator==(const String& s1, const String& s2); bool operator!=(const String& s1, const String& s2); bool operator< (const String& s1, const String& s2); bool operator<= (const String& s1, const String& s2); bool operator> (const String& s1, const String& s2); bool operator>= (const String& s1, const String& s2);
string.cpp:
#include"string.h" pairString::alloc_n_copy(const char*b, const char*e) { auto str = alloc.allocate(e - b); return { str,uninitialized_copy(b,e,str) }; } void String::range_initializer(const char*b, const char*e) { auto newstr = alloc_n_copy(b, e); elements = newstr.first; end = newstr.second; } String::String(const char*s) { char* s1 = const_cast (s); while (*s1) { ++s1; } range_initializer(s, ++s1); } String::String(const String&rhs) { range_initializer(rhs.elements, rhs.end); cout << "copy constructor" << endl; } void String::free() { if (elements) { for_each(elements, end, [this](char& c) {alloc.destroy(&c); }); alloc.deallocate(elements, end - elements); } } String::~String() { free(); } String& String::operator=(const String&rhs) { auto newstr = alloc_n_copy(rhs.elements, rhs.end); free(); elements = newstr.first; end = newstr.second; cout << "copy assignment" << endl; return *this; } String::String(String&&s)noexcept:elements(s.elements),end(s.end) { s.elements = s.end = nullptr; } String& String::operator=(String&&s)noexcept { if (this != &s) { free(); elements = s.elements; end = s.end; s.elements = s.end = nullptr; } return *this; } ostream& operator<< (ostream& os, const String& s) { char* c = const_cast (s.c_str()); while (*c) { os << *c++; } return os; } bool operator==(const String& s1, const String& s2) { return s1.size() == s2.size() && equal(s1.elements, s1.end, s2.elements); } bool operator!=(const String& s1, const String& s2) { return !(s1 == s2); } bool operator< (const String& s1, const String& s2) { return lexicographical_compare(s1.elements, s1.end, s2.elements, s2.end); } bool operator<= (const String& s1, const String& s2) { return !(s2 < s1); } bool operator> (const String& s1, const String& s2) { return s2 < s1; } bool operator>= (const String& s1, const String& s2) { return !(s1 < s2); }
14.22:
#pragma once #includeusing namespace std; #include #include class Sales_data { friend istream& read(istream& is, Sales_data& item); friend ostream& print(ostream& os, const Sales_data& item); friend Sales_data add(const Sales_data& s1, const Sales_data& s2); friend istream& operator>>(istream& , Sales_data&); friend ostream& operator<<(ostream& , const Sales_data&); friend Sales_data operator+(const Sales_data& s1, const Sales_data& s2); friend Sales_data operator-(const Sales_data& s1, const Sales_data& s2); public: Sales_data() = default; Sales_data(const string& s) :bookNo(s) {}; Sales_data(const string& s, unsigned n, double p) :bookNo(s), unit_sold(n), revenue(n* p) {}; Sales_data(istream& is) { read(cin, *this); } Sales_data& operator+=(const Sales_data& s); Sales_data& operator-=(const Sales_data& s); Sales_data& operator=(const string& s); Sales_data& combine(const Sales_data& rhs); string isbn()const { return this->bookNo; } private: inline double avg_price()const; string bookNo; unsigned unit_sold = 0; double revenue = 0.0; }; Sales_data& Sales_data::combine(const Sales_data& rhs) { this->unit_sold += rhs.unit_sold; this->revenue += rhs.revenue; return *this; } Sales_data add(const Sales_data& s1, const Sales_data& s2) { Sales_data temp = s1; temp.combine(s2); return temp; } istream& read(istream& is, Sales_data& item) { double price = 0; is >> item.bookNo >> item.unit_sold >> price; item.revenue = item.unit_sold * price; return is; } ostream& print(ostream& os, const Sales_data& item) { os << item.bookNo << " " << item.unit_sold << " " << item.revenue; return os; } inline double Sales_data::avg_price()const { return unit_sold ? revenue / unit_sold : 0; } istream& operator>>(istream& in, Sales_data& sd) { double price = 0; in >> sd.bookNo >> sd.unit_sold >> price; if (in) { sd.revenue = sd.unit_sold * price; } else { sd = Sales_data(); } return in; } ostream& operator<<(ostream& out, const Sales_data& item) { out << item.bookNo << " " << item.unit_sold << " " << item.revenue << " " << item.avg_price(); return out; } Sales_data operator+(const Sales_data& s1, const Sales_data & s2) { Sales_data temp = s1; temp.unit_sold += s2.unit_sold; temp.revenue += s2.revenue; return temp; } Sales_data& Sales_data::operator+=(const Sales_data& s) { this->unit_sold += s.unit_sold; this->revenue += s.revenue; return *this; } Sales_data operator-(const Sales_data& s1, const Sales_data& s2) { Sales_data temp = s1; temp -= s2; return temp; } Sales_data& Sales_data::operator-=(const Sales_data& s) { this->unit_sold -= s.unit_sold; this->revenue -= s.revenue; return *this; } Sales_data& Sales_data::operator=(const string& s) { *this = Sales_data(s); return *this; }
14.27:
.h
#include "ex14_27_28_StrBlob.h"
#include
//==================================================================
//
// StrBlob - operators
//
//==================================================================
bool operator==(const StrBlob &lhs, const StrBlob &rhs)
{
return *lhs.data == *rhs.data;
}
bool operator!=(const StrBlob &lhs, const StrBlob &rhs)
{
return !(lhs == rhs);
}
bool operator< (const StrBlob &lhs, const StrBlob &rhs)
{
return std::lexicographical_compare(lhs.data->begin(), lhs.data->end(), rhs.data->begin(), rhs.data->end());
}
bool operator> (const StrBlob &lhs, const StrBlob &rhs)
{
return rhs < lhs;
}
bool operator<=(const StrBlob &lhs, const StrBlob &rhs)
{
return !(rhs < lhs);
}
bool operator>=(const StrBlob &lhs, const StrBlob &rhs)
{
return !(lhs < rhs);
}
//================================================================
//
// StrBlobPtr - operators
//
//================================================================
bool operator==(const StrBlobPtr &lhs, const StrBlobPtr &rhs)
{
return lhs.curr == rhs.curr;
}
bool operator!=(const StrBlobPtr &lhs, const StrBlobPtr &rhs)
{
return !(lhs == rhs);
}
bool operator< (const StrBlobPtr &x, const StrBlobPtr &y)
{
return x.curr < y.curr;
}
bool operator>(const StrBlobPtr &x, const StrBlobPtr &y)
{
return x.curr > y.curr;
}
bool operator<=(const StrBlobPtr &x, const StrBlobPtr &y)
{
return x.curr <= y.curr;
}
bool operator>=(const StrBlobPtr &x, const StrBlobPtr &y)
{
return x.curr >= y.curr;
}
//================================================================
//
// ConstStrBlobPtr - operators
//
//================================================================
bool operator==(const ConstStrBlobPtr &lhs, const ConstStrBlobPtr &rhs)
{
return lhs.curr == rhs.curr;
}
bool operator!=(const ConstStrBlobPtr &lhs, const ConstStrBlobPtr &rhs)
{
return !(lhs == rhs);
}
bool operator< (const ConstStrBlobPtr &lhs, const ConstStrBlobPtr &rhs)
{
return lhs.curr < rhs.curr;
}
bool operator>(const ConstStrBlobPtr &lhs, const ConstStrBlobPtr &rhs)
{
return lhs.curr > rhs.curr;
}
bool operator<=(const ConstStrBlobPtr &lhs, const ConstStrBlobPtr &rhs)
{
return lhs.curr <= rhs.curr;
}
bool operator>=(const ConstStrBlobPtr &lhs, const ConstStrBlobPtr &rhs)
{
return lhs.curr >= rhs.curr;
}
//==================================================================
//
// copy assignment operator and move assignment operator.
//
//==================================================================
StrBlob& StrBlob::operator=(const StrBlob &lhs)
{
data = make_shared>(*lhs.data);
return *this;
}
StrBlob& StrBlob::operator=(StrBlob &&rhs) NOEXCEPT
{
if (this != &rhs) {
data = std::move(rhs.data);
rhs.data = nullptr;
}
return *this;
}
//==================================================================
//
// members
//
//==================================================================
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());
}
.cpp
#include "StrBlob.h"
#include
//==================================================================
//
// StrBlob - operators
//
//==================================================================
bool operator==(const StrBlob& lhs, const StrBlob& rhs)
{
return *lhs.data == *rhs.data;
}
bool operator!=(const StrBlob& lhs, const StrBlob& rhs)
{
return !(lhs == rhs);
}
bool operator< (const StrBlob& lhs, const StrBlob& rhs)
{
return std::lexicographical_compare(lhs.data->begin(), lhs.data->end(), rhs.data->begin(), rhs.data->end());
}
bool operator> (const StrBlob& lhs, const StrBlob& rhs)
{
return rhs < lhs;
}
bool operator<=(const StrBlob& lhs, const StrBlob& rhs)
{
return !(rhs < lhs);
}
bool operator>=(const StrBlob& lhs, const StrBlob& rhs)
{
return !(lhs < rhs);
}
//================================================================
//
// StrBlobPtr - operators
//
//================================================================
bool operator==(const StrBlobPtr& lhs, const StrBlobPtr& rhs)
{
return lhs.curr == rhs.curr;
}
bool operator!=(const StrBlobPtr& lhs, const StrBlobPtr& rhs)
{
return !(lhs == rhs);
}
bool operator< (const StrBlobPtr& x, const StrBlobPtr& y)
{
return x.curr < y.curr;
}
bool operator>(const StrBlobPtr& x, const StrBlobPtr& y)
{
return x.curr > y.curr;
}
bool operator<=(const StrBlobPtr& x, const StrBlobPtr& y)
{
return x.curr <= y.curr;
}
bool operator>=(const StrBlobPtr& x, const StrBlobPtr& y)
{
return x.curr >= y.curr;
}
//================================================================
//
// ConstStrBlobPtr - operators
//
//================================================================
bool operator==(const ConstStrBlobPtr& lhs, const ConstStrBlobPtr& rhs)
{
return lhs.curr == rhs.curr;
}
bool operator!=(const ConstStrBlobPtr& lhs, const ConstStrBlobPtr& rhs)
{
return !(lhs == rhs);
}
bool operator< (const ConstStrBlobPtr& lhs, const ConstStrBlobPtr& rhs)
{
return lhs.curr < rhs.curr;
}
bool operator>(const ConstStrBlobPtr& lhs, const ConstStrBlobPtr& rhs)
{
return lhs.curr > rhs.curr;
}
bool operator<=(const ConstStrBlobPtr& lhs, const ConstStrBlobPtr& rhs)
{
return lhs.curr <= rhs.curr;
}
bool operator>=(const ConstStrBlobPtr& lhs, const ConstStrBlobPtr& rhs)
{
return lhs.curr >= rhs.curr;
}
//==================================================================
//
// copy assignment operator and move assignment operator.
//
//==================================================================
StrBlob& StrBlob::operator=(const StrBlob& lhs)
{
data = make_shared>(*lhs.data);
return *this;
}
StrBlob& StrBlob::operator=(StrBlob&& rhs) NOEXCEPT
{
if (this != &rhs) {
data = std::move(rhs.data);
rhs.data = nullptr;
}
return *this;
}
//==================================================================
//
// members
//
//==================================================================
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());
}
14.30:
.h:
#ifndef CP5_STRBLOB_H_ #define CP5_STRBLOB_H_ using namespace std; #include#include #include #include #include #include #ifndef _MSC_VER #define NOEXCEPT noexcept #else #define NOEXCEPT #endif class StrBlobPtr; class ConstStrBlobPtr; //================================================================================= // // StrBlob - custom vector // //================================================================================= class StrBlob { using size_type = vector ::size_type; friend class ConstStrBlobPtr; friend class StrBlobPtr; friend bool operator==(const StrBlob&, const StrBlob&); friend bool operator!=(const StrBlob&, const StrBlob&); friend bool operator< (const StrBlob&, const StrBlob&); friend bool operator> (const StrBlob&, const StrBlob&); friend bool operator<=(const StrBlob&, const StrBlob&); friend bool operator>=(const StrBlob&, const StrBlob&); public: StrBlob() : data(make_shared >()) { } StrBlob(initializer_list il) : data(make_shared >(il)) { } StrBlob(const StrBlob& sb) : data(make_shared >(*sb.data)) { } StrBlob& operator=(const StrBlob&); StrBlob(StrBlob&& rhs) NOEXCEPT : data(std::move(rhs.data)) { } StrBlob& operator=(StrBlob&&)NOEXCEPT; StrBlobPtr begin(); StrBlobPtr end(); ConstStrBlobPtr cbegin() const; ConstStrBlobPtr cend() const; string& operator[](size_t n); const string& operator[](size_t n) const; size_type size() const { return data->size(); } bool empty() const { return data->empty(); } void push_back(const string& t) { data->push_back(t); } void push_back(string&& s) { data->push_back(std::move(s)); } void pop_back(); string& front(); string& back(); const string& front() const; const string& back() const; private: void check(size_type, const string&) const; shared_ptr > data; }; bool operator==(const StrBlob&, const StrBlob&); bool operator!=(const StrBlob&, const StrBlob&); bool operator< (const StrBlob&, const StrBlob&); bool operator> (const StrBlob&, const StrBlob&); bool operator<=(const StrBlob&, const StrBlob&); bool operator>=(const StrBlob&, const StrBlob&); inline void StrBlob::pop_back() { check(0, "pop_back on empty StrBlob"); data->pop_back(); } inline string& StrBlob::front() { check(0, "front on empty StrBlob"); return data->front(); } inline string& StrBlob::back() { check(0, "back on empty StrBlob"); return data->back(); } inline const string& StrBlob::front() const { check(0, "front on empty StrBlob"); return data->front(); } inline const string& StrBlob::back() const { check(0, "back on empty StrBlob"); return data->back(); } inline void StrBlob::check(size_type i, const string& msg) const { if (i >= data->size()) throw out_of_range(msg); } inline string& StrBlob::operator[](size_t n) { check(n, "out of range"); return data->at(n); } inline const string& StrBlob::operator[](size_t n) const { check(n, "out of range"); return data->at(n); } //================================================================================= // // StrBlobPtr - custom iterator of StrBlob // //================================================================================= class StrBlobPtr { friend bool operator==(const StrBlobPtr&, const StrBlobPtr&); friend bool operator!=(const StrBlobPtr&, const StrBlobPtr&); friend bool operator< (const StrBlobPtr&, const StrBlobPtr&); friend bool operator> (const StrBlobPtr&, const StrBlobPtr&); friend bool operator<=(const StrBlobPtr&, const StrBlobPtr&); friend bool operator>=(const StrBlobPtr&, const StrBlobPtr&); public: StrBlobPtr() : curr(0) { } StrBlobPtr(StrBlob& s, size_t sz = 0) : wptr(s.data), curr(sz) { } string& deref() const; StrBlobPtr& operator++(); StrBlobPtr& operator--(); StrBlobPtr operator++(int); StrBlobPtr operator--(int); StrBlobPtr& operator+=(size_t); StrBlobPtr& operator-=(size_t); StrBlobPtr operator+(size_t) const; StrBlobPtr operator-(size_t) const; string& operator*() const; string* operator->() const; string& operator[](size_t n); const string& operator[](size_t n) const; private: shared_ptr > check(size_t, const string&) const; std::weak_ptr > wptr; size_t curr; }; bool operator==(const StrBlobPtr&, const StrBlobPtr&); bool operator!=(const StrBlobPtr&, const StrBlobPtr&); bool operator< (const StrBlobPtr&, const StrBlobPtr&); bool operator> (const StrBlobPtr&, const StrBlobPtr&); bool operator<=(const StrBlobPtr&, const StrBlobPtr&); bool operator>=(const StrBlobPtr&, const StrBlobPtr&); inline string& StrBlobPtr::deref() const { auto p = check(curr, "dereference past end"); return (*p)[curr]; } inline StrBlobPtr& StrBlobPtr::operator++() { check(curr, "increment past end of StrBlobPtr"); ++curr; return *this; } inline StrBlobPtr& StrBlobPtr::operator--() { check(--curr, "decrement past begin of StrBlobPtr"); return *this; } inline StrBlobPtr StrBlobPtr::operator++(int) { StrBlobPtr ret = *this; ++* this; return ret; } inline StrBlobPtr StrBlobPtr::operator--(int) { StrBlobPtr ret = *this; --* this; return ret; } inline StrBlobPtr& StrBlobPtr::operator+=(size_t n) { curr += n; check(curr, "increment past end of StrBlobPtr"); return *this; } inline StrBlobPtr& StrBlobPtr::operator-=(size_t n) { curr -= n; check(curr, "increment past end of StrBlobPtr"); return *this; } inline StrBlobPtr StrBlobPtr::operator+(size_t n) const { StrBlobPtr ret = *this; ret += n; return ret; } inline StrBlobPtr StrBlobPtr::operator-(size_t n) const { StrBlobPtr ret = *this; ret -= n; return ret; } inline shared_ptr > StrBlobPtr::check(size_t i, const string& msg) const { auto ret = wptr.lock(); if (!ret) throw std::runtime_error("unbound StrBlobPtr"); if (i >= ret->size()) throw std::out_of_range(msg); return ret; } inline string& StrBlobPtr::operator[](size_t n) { auto p = check(n, "dereference out of range."); return (*p)[n]; } inline const string& StrBlobPtr::operator[](size_t n) const { auto p = check(n, "dereference out of range."); return (*p)[n]; } inline string& StrBlobPtr::operator*() const { auto p = check(curr, "dereference past end"); return (*p)[curr]; } inline string* StrBlobPtr::operator->() const { return &this->operator*(); } //================================================================================= // // ConstStrBlobPtr - custom const_iterator of StrBlob // //================================================================================= class ConstStrBlobPtr { friend bool operator==(const ConstStrBlobPtr&, const ConstStrBlobPtr&); friend bool operator!=(const ConstStrBlobPtr&, const ConstStrBlobPtr&); friend bool operator< (const ConstStrBlobPtr&, const ConstStrBlobPtr&); friend bool operator> (const ConstStrBlobPtr&, const ConstStrBlobPtr&); friend bool operator<=(const ConstStrBlobPtr&, const ConstStrBlobPtr&); friend bool operator>=(const ConstStrBlobPtr&, const ConstStrBlobPtr&); public: ConstStrBlobPtr() : curr(0) { } ConstStrBlobPtr(const StrBlob& s, size_t sz = 0) : wptr(s.data), curr(sz) { } const string& deref() const; ConstStrBlobPtr& operator++(); ConstStrBlobPtr& operator--(); ConstStrBlobPtr operator++(int); ConstStrBlobPtr operator--(int); ConstStrBlobPtr& operator+=(size_t); ConstStrBlobPtr& operator-=(size_t); ConstStrBlobPtr operator+(size_t) const; ConstStrBlobPtr operator-(size_t) const; const string& operator*() const; const string* operator->() const; const string& operator[](size_t n) const; private: std::shared_ptr > check(size_t, const string&) const; std::weak_ptr > wptr; size_t curr; }; bool operator==(const ConstStrBlobPtr&, const ConstStrBlobPtr&); bool operator!=(const ConstStrBlobPtr&, const ConstStrBlobPtr&); bool operator< (const ConstStrBlobPtr&, const ConstStrBlobPtr&); bool operator> (const ConstStrBlobPtr&, const ConstStrBlobPtr&); bool operator<=(const ConstStrBlobPtr&, const ConstStrBlobPtr&); bool operator>=(const ConstStrBlobPtr&, const ConstStrBlobPtr&); inline const string& ConstStrBlobPtr::deref() const { auto p = check(curr, "dereference past end"); return (*p)[curr]; } inline ConstStrBlobPtr& ConstStrBlobPtr::operator++() { check(curr, "increment past end of ConstStrBlobPtr"); ++curr; return *this; } inline ConstStrBlobPtr& ConstStrBlobPtr::operator--() { --curr; check(-1, "decrement past begin of ConstStrBlobPtr"); return *this; } inline ConstStrBlobPtr ConstStrBlobPtr::operator++(int) { ConstStrBlobPtr ret = *this; ++* this; return ret; } inline ConstStrBlobPtr ConstStrBlobPtr::operator--(int) { ConstStrBlobPtr ret = *this; --* this; return ret; } inline ConstStrBlobPtr& ConstStrBlobPtr::operator+=(size_t n) { curr += n; check(curr, "increment past end of ConstStrBlobPtr"); return *this; } inline ConstStrBlobPtr& ConstStrBlobPtr::operator-=(size_t n) { curr -= n; check(curr, "increment past end of ConstStrBlobPtr"); return *this; } inline ConstStrBlobPtr ConstStrBlobPtr::operator+(size_t n) const { ConstStrBlobPtr ret = *this; ret += n; return ret; } inline ConstStrBlobPtr ConstStrBlobPtr::operator-(size_t n) const { ConstStrBlobPtr ret = *this; ret -= n; return ret; } inline std::shared_ptr > ConstStrBlobPtr::check(size_t i, const string& msg) const { auto ret = wptr.lock(); if (!ret) throw std::runtime_error("unbound StrBlobPtr"); if (i >= ret->size()) throw std::out_of_range(msg); return ret; } inline const string& ConstStrBlobPtr::operator[](size_t n) const { auto p = check(n, "dereference out of range."); return (*p)[n]; } inline const string& ConstStrBlobPtr::operator*() const { auto p = check(curr, "dereference past end"); return (*p)[curr]; } inline const string* ConstStrBlobPtr::operator->() const { return &this->operator*(); } #endif
.cpp:
#include "StrBlob.h"
#include
//==================================================================
//
// StrBlob - operators
//
//==================================================================
bool operator==(const StrBlob& lhs, const StrBlob& rhs)
{
return *lhs.data == *rhs.data;
}
bool operator!=(const StrBlob& lhs, const StrBlob& rhs)
{
return !(lhs == rhs);
}
bool operator< (const StrBlob& lhs, const StrBlob& rhs)
{
return std::lexicographical_compare(lhs.data->begin(), lhs.data->end(), rhs.data->begin(), rhs.data->end());
}
bool operator> (const StrBlob& lhs, const StrBlob& rhs)
{
return rhs < lhs;
}
bool operator<=(const StrBlob& lhs, const StrBlob& rhs)
{
return !(rhs < lhs);
}
bool operator>=(const StrBlob& lhs, const StrBlob& rhs)
{
return !(lhs < rhs);
}
//================================================================
//
// StrBlobPtr - operators
//
//================================================================
bool operator==(const StrBlobPtr& lhs, const StrBlobPtr& rhs)
{
return lhs.curr == rhs.curr;
}
bool operator!=(const StrBlobPtr& lhs, const StrBlobPtr& rhs)
{
return !(lhs == rhs);
}
bool operator< (const StrBlobPtr& x, const StrBlobPtr& y)
{
return x.curr < y.curr;
}
bool operator>(const StrBlobPtr& x, const StrBlobPtr& y)
{
return x.curr > y.curr;
}
bool operator<=(const StrBlobPtr& x, const StrBlobPtr& y)
{
return x.curr <= y.curr;
}
bool operator>=(const StrBlobPtr& x, const StrBlobPtr& y)
{
return x.curr >= y.curr;
}
//================================================================
//
// ConstStrBlobPtr - operators
//
//================================================================
bool operator==(const ConstStrBlobPtr& lhs, const ConstStrBlobPtr& rhs)
{
return lhs.curr == rhs.curr;
}
bool operator!=(const ConstStrBlobPtr& lhs, const ConstStrBlobPtr& rhs)
{
return !(lhs == rhs);
}
bool operator< (const ConstStrBlobPtr& lhs, const ConstStrBlobPtr& rhs)
{
return lhs.curr < rhs.curr;
}
bool operator>(const ConstStrBlobPtr& lhs, const ConstStrBlobPtr& rhs)
{
return lhs.curr > rhs.curr;
}
bool operator<=(const ConstStrBlobPtr& lhs, const ConstStrBlobPtr& rhs)
{
return lhs.curr <= rhs.curr;
}
bool operator>=(const ConstStrBlobPtr& lhs, const ConstStrBlobPtr& rhs)
{
return lhs.curr >= rhs.curr;
}
//==================================================================
//
// copy assignment operator and move assignment operator.
//
//==================================================================
StrBlob& StrBlob::operator=(const StrBlob& lhs)
{
data = make_shared>(*lhs.data);
return *this;
}
StrBlob& StrBlob::operator=(StrBlob&& rhs) NOEXCEPT
{
if (this != &rhs) {
data = std::move(rhs.data);
rhs.data = nullptr;
}
return *this;
}
//==================================================================
//
// members
//
//==================================================================
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());
}
14.32:
.h
#ifndef STRBLOBPTR_POINTER_H
#define STRBLOBPTR_POINTER_H
class StrBlobPtr;
class StrBlobPtr_pointer
{
public:
StrBlobPtr_pointer() = default;
StrBlobPtr_pointer(StrBlobPtr* p) : pointer(p) { }
StrBlobPtr& operator *() const;
StrBlobPtr* operator->() const;
private:
StrBlobPtr* pointer = nullptr;
};
#endif // STRBLOBPTR_POINTER_H
.cpp:
#include "ex14_32.h" #include "ex14_30_StrBlob.h" #includeStrBlobPtr& StrBlobPtr_pointer::operator *() const { return *pointer; } StrBlobPtr* StrBlobPtr_pointer::operator ->() const { return pointer; } int main() { StrBlob sb{ "hello", "world" }; StrBlobPtr iter = sb.begin(); StrBlobPtr_pointer p(&iter); std::cout << p->deref() << std::endl; }
14.34:
#includeusing namespace std; class if_then_else { public: int operator()(int a, int b, int c) { return (a ? b : c); } }; int main() { int a = 0, b = 1, c = 2; if_then_else f; cout << f(a, b, c) << endl; }
14.35:
#includeusing namespace std; #include class PrintString { public: PrintString(istream&i =cin):is(i){} string operator()() { string str; getline(is, str); return is ? str : string(); } private: istream& is; }; int main() { PrintString getinput; cout << getinput() << endl; }
14.36:
#includeusing namespace std; #include #include class PrintString { public: PrintString(istream&i =cin):is(i){} string operator()() { string str; getline(is, str); return is ? str : string(); } private: istream& is; }; int main() { PrintString getinput; vector ves; for (string temp; !((temp = getinput()).empty()); ves.push_back(temp)); for (auto m : ves) { cout << m << " "; }cout << endl; return 0; }
14.37:
#includeusing namespace std; #include #include #include class test { public: test(int a):i(a){} bool operator()(const int& b) { return i == b; } private: int i; }; int main() { test t(1); vector vec = { 1,2,3,4,5,6,7,9 }; replace_if(vec.begin(), vec.end(), t, 2); for (int i : vec) cout << i << " "; cout << endl; return 0; }
10.39:
哈哈哈
#includeusing namespace std; #include #include #include class SizeComp { public: SizeComp(size_t i):sz(i),lower(0),upper(0) {} SizeComp(size_t a,size_t b) :sz(0), lower(a), upper(b) {} SizeComp(size_t a, size_t b,size_t c) :sz(c), lower(a), upper(b) {} bool operator()(const string& s)const { if (sz==0) { return s.size() >= lower && s.size() <= upper; } else if(lower ==0) { return s.size() == sz; } else { return s.size() >= upper; } } private: size_t sz; size_t lower; size_t upper; }; int main() { vector ves = { "sdafsdf","asdfasdf","as","wre","qwer","a","sdfsdfsdfasdfsdf"}; auto num = count_if(ves.begin(), ves.end(), SizeComp(2)); cout << num << endl; num = count_if(ves.begin(), ves.end(), SizeComp(1,9)); cout << num << endl; num = count_if(ves.begin(), ves.end(), SizeComp(10,10,10)); cout << num << endl; return 0; }
14.40:
class ShorterString {
public:
bool operator()(string const& s1, string const& s2) const { return s1.size() < s2.size(); }
};
class BiggerEqual {
size_t sz_;
public:
BiggerEqual(size_t sz) : sz_(sz) { }
bool operator()(string const& s) { return s.size() >= sz_; }
};
class Print {
public:
void operator()(string const& s) { cout << s << " "; }
};
14.42:
count_if(vec.begin(), vec.end(), bind(greater(), _1, 1024)); find_if(vec.begin(), vec.end(), bind(not_equal_to (), _1, "ppoh")); transform(vec.begin(), vec.end(), vec.begin(), bind(multiplies (), _1, 2));
14.43:
#includeusing namespace std; #include #include #include #include using placeholders::_1; int main() { vector vec = { 2,4,8 }; int i = 0; int input; cin >> input; bool b = any_of(vec.begin(), vec.end(), bind(modulus (), input, _1)); if (b) cout << "not!" << endl; else cout << "yes!" << endl; return 0; }
14.44:
#includeusing namespace std; #include #include
14.45:
#pragma once #includeusing namespace std; #include #include class Sales_data { friend istream& read(istream& is, Sales_data& item); friend ostream& print(ostream& os, const Sales_data& item); friend Sales_data add(const Sales_data& s1, const Sales_data& s2); friend istream& operator>>(istream& , Sales_data&); friend ostream& operator<<(ostream& , const Sales_data&); friend Sales_data operator+(const Sales_data& s1, const Sales_data& s2); friend Sales_data operator-(const Sales_data& s1, const Sales_data& s2); public: Sales_data() = default; Sales_data(const string& s) :bookNo(s) {}; Sales_data(const string& s, unsigned n, double p) :bookNo(s), unit_sold(n), revenue(n* p) {}; Sales_data(istream& is) { read(cin, *this); } Sales_data& operator+=(const Sales_data& s); Sales_data& operator-=(const Sales_data& s); Sales_data& operator=(const string& s); explicit operator string() const { return this->bookNo; } explicit operator double() const { return this->avg_price(); } Sales_data& combine(const Sales_data& rhs); string isbn()const { return this->bookNo; } private: inline double avg_price()const; string bookNo; unsigned unit_sold = 0; double revenue = 0.0; }; Sales_data& Sales_data::combine(const Sales_data& rhs) { this->unit_sold += rhs.unit_sold; this->revenue += rhs.revenue; return *this; } Sales_data add(const Sales_data& s1, const Sales_data& s2) { Sales_data temp = s1; temp.combine(s2); return temp; } istream& read(istream& is, Sales_data& item) { double price = 0; is >> item.bookNo >> item.unit_sold >> price; item.revenue = item.unit_sold * price; return is; } ostream& print(ostream& os, const Sales_data& item) { os << item.bookNo << " " << item.unit_sold << " " << item.revenue; return os; } inline double Sales_data::avg_price()const { return unit_sold ? revenue / unit_sold : 0; } istream& operator>>(istream& in, Sales_data& sd) { double price = 0; in >> sd.bookNo >> sd.unit_sold >> price; if (in) { sd.revenue = sd.unit_sold * price; } else { sd = Sales_data(); } return in; } ostream& operator<<(ostream& out, const Sales_data& item) { out << item.bookNo << " " << item.unit_sold << " " << item.revenue << " " << item.avg_price(); return out; } Sales_data operator+(const Sales_data& s1, const Sales_data & s2) { Sales_data temp = s1; temp.unit_sold += s2.unit_sold; temp.revenue += s2.revenue; return temp; } Sales_data& Sales_data::operator+=(const Sales_data& s) { this->unit_sold += s.unit_sold; this->revenue += s.revenue; return *this; } Sales_data operator-(const Sales_data& s1, const Sales_data& s2) { Sales_data temp = s1; temp -= s2; return temp; } Sales_data& Sales_data::operator-=(const Sales_data& s) { this->unit_sold -= s.unit_sold; this->revenue -= s.revenue; return *this; } Sales_data& Sales_data::operator=(const string& s) { *this = Sales_data(s); return *this; }



