14.2:
#pragma once
#include<iostream>
using namespace std;
#include<string>
#include<fstream>
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
#include<iostream>
using namespace std;
#include<algorithm>
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<char*, char*>alloc_n_copy(const char*, const char*);
void range_initializer(const char*, const char*);
void free();
char* elements;
char* end;
allocator<char>alloc;
};
ostream& operator<< (ostream& os, const String& s);
String.cpp:
#include"string.h"
pair<char*, char*>String::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<char*>(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<char*>(s.c_str());
while (*c)
{
os << *c++;
}
return os;
}
14.13:
#pragma once
#include<iostream>
using namespace std;
#include<string>
#include<fstream>
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
#include<iostream>
using namespace std;
#include<algorithm>
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<char*, char*>alloc_n_copy(const char*, const char*);
void range_initializer(const char*, const char*);
void free();
char* elements;
char* end;
allocator<char>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"
pair<char*, char*>String::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<char*>(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<char*>(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
#include<iostream>
using namespace std;
#include<algorithm>
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<char*, char*>alloc_n_copy(const char*, const char*);
void range_initializer(const char*, const char*);
void free();
char* elements;
char* end;
allocator<char>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"
pair<char*, char*>String::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<char*>(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<char*>(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
#include<iostream>
using namespace std;
#include<string>
#include<fstream>
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 <algorithm>
//==================================================================
//
// 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<vector<string>>(*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 <algorithm>
//==================================================================
//
// 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<vector<string>>(*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<iostream>
#include <vector>
#include <string>
#include <initializer_list>
#include <memory>
#include <exception>
#ifndef _MSC_VER
#define NOEXCEPT noexcept
#else
#define NOEXCEPT
#endif
class StrBlobPtr;
class ConstStrBlobPtr;
//=================================================================================
//
// StrBlob - custom vector<string>
//
//=================================================================================
class StrBlob {
using size_type = vector<string>::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<vector<string>>()) { }
StrBlob(initializer_list<string> il) : data(make_shared<vector<string>>(il)) { }
StrBlob(const StrBlob& sb) : data(make_shared<vector<string>>(*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<vector<string>> 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<vector<string>> check(size_t, const string&) const;
std::weak_ptr<vector<string>> 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<vector<string>> 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<vector<string>> check(size_t, const string&) const;
std::weak_ptr<vector<string>> 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<vector<string>> 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 <algorithm>
//==================================================================
//
// 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<vector<string>>(*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;
/**
* @brief a class that holds a pointer to a 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"
#include <iostream>
StrBlobPtr&
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:
#include<iostream>
using 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:
#include<iostream>
using namespace std;
#include<string>
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:
#include<iostream>
using namespace std;
#include<string>
#include<vector>
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<string>ves;
for (string temp; !((temp = getinput()).empty()); ves.push_back(temp));
for (auto m : ves) { cout << m << " "; }cout << endl;
return 0;
}
14.37:
#include<iostream>
using namespace std;
#include<string>
#include<vector>
#include<algorithm>
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<int>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:
哈哈哈
#include<iostream>
using namespace std;
#include<string>
#include<vector>
#include<algorithm>
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<string>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<int>(), _1, 1024));
find_if(vec.begin(), vec.end(), bind(not_equal_to<string>(), _1, "ppoh"));
transform(vec.begin(), vec.end(), vec.begin(), bind(multiplies<int>(), _1, 2));
14.43:
#include<iostream>
using namespace std;
#include<string>
#include<vector>
#include<algorithm>
#include<functional>
using placeholders::_1;
int main()
{
vector<int>vec = { 2,4,8 };
int i = 0;
int input;
cin >> input;
bool b = any_of(vec.begin(), vec.end(), bind(modulus<int>(), input, _1));
if (b)
cout << "not!" << endl;
else
cout << "yes!" << endl;
return 0;
}
14.44:
#include<iostream>
using namespace std;
#include<functional>
#include<map>
//普通函数
int add(int a, int b)
{
return a + b;
}
//lambda
auto mod = [](int a, int b) {return a % b; };
//函数对象类
class divide
{
public:
int operator()(int a, int b)
{
return a / b;
}
};
int main()
{
int(*p1)(int, int) = add;
map<string, function<int(int, int)>>binops = {
{"+",p1},
{"-",minus<int>()},
{"/",divide()},
{"*",[](int i,int j) {return i * j; }},
{"%",mod}
};
while (cout << "Pls enter as: num operator num :\n", true)
{
int lhs, rhs;string op;
cin >> lhs >> op >> rhs;
cout << binops[op](lhs, rhs) << endl;
}
return 0;
}
14.45:
#pragma once
#include<iostream>
using namespace std;
#include<string>
#include<fstream>
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;
}