#include<iostream>
template<typename T>
int compare(const T& v1, const T& v2)
{
if (v1 < v2) return -1;
if (v2 < v1) return 1;
return 0;
}
int main()
{
std::cout << compare(1, 2) << std::endl;
}
#include<iostream>
#include<vector>
#include<list>
#include<string>
template<typename Iter,typename T>
Iter find(const Iter beg, const Iter end, const T& val)
{
for (Iter it = beg; it != end; ++it)
{
if (*it == val)
return it;
}
}
int main()
{
std::vector<int>vi = { 1,2,3,4,5 };
std::list < std::string > ls = { "aaa","bbb","ccc" };
std::cout << *(::find(vi.begin(), vi.end(), 3)) << std::endl;
std::cout << *(::find(ls.begin(), ls.end(), "ccc")) << std::endl;
return 0;
}
#include<iostream>
#include<string>
template<typename T>
void print(const T& arr)
{
for (auto elem : arr)
std::cout << elem << std::endl;
}
int main()
{
int a1[] = { 1,5,2,3,6 };
char b1[] = "hello";
print(a1);
print(b1);
return 0;
}
#include<iostream>
#include<string>
template<typename T,unsigned N>
T* begin(T(&arr)[N])
{
return arr;
}
template<typename T, unsigned N>
T* end(T(&arr)[N])
{
return arr + N;
}
int main()
{
char a[] = "hello";
std::cout << *(begin(a)) << std::endl;
std::cout << *(end(a)-2) << std::endl;
return 0;
}
#include<iostream>
#include<string>
template<typename T,unsigned size>
constexpr unsigned getSize(const T(&)[size])
{
return size;
}
int main()
{
char a1[] = "hello";
std::cout << getSize(a1) << std::endl;
return 0;
}
#ifndef STRBLOB_H_
#define STRBLOB_H_
#include<iostream>
#include<vector>
#include<memory>
#include<initializer_list>
#include<stdexcept>
template<typename T>
class ConstStrBlobPtr;
template<typename T>
class StrBlob
{
public:
friend class ConstStrBlobPtr<T>;
typedef typename std::vector<T>::size_type size_type;
StrBlob();
StrBlob(std::initializer_list<T> il);
size_type size()const { return data->size(); }
bool empty()const { return data->empty(); }
void push_back(const T& t) { data->push_back(t); }
void pop_back();
T& front();
T& back();
const T& front()const;
const T& back()const;
ConstStrBlobPtr<T> begin();
ConstStrBlobPtr<T>end();
private:
std::shared_ptr<std::vector<T>> data;
void check(size_type i, const T& msg)const;
};
template <typename T>
class ConstStrBlobPtr
{
public:
ConstStrBlobPtr<T>() :curr(0) {}
ConstStrBlobPtr<T>(const StrBlob<T>& a, size_t sz = 0) : wptr(a.data), curr(sz) {}
T& deref()const;
ConstStrBlobPtr<T>& incr();
private:
std::shared_ptr<std::vector<T>> check(std::size_t, const T&)const;
std::weak_ptr<std::vector<int>> wptr;
std::size_t curr;
};
template<typename T>
std::shared_ptr<std::vector<T>> ConstStrBlobPtr<T>::check(std::size_t i, const T& msg)const
{
auto ret = wptr.lock();
if (!ret)
throw std::runtime_error("unbound ConstStrBlobPtr<T>");
if (i > ret.size())
throw std::out_of_range(msg);
return ret;
}
template<typename T>
ConstStrBlobPtr <T>& ConstStrBlobPtr<T>::incr()
{
check(curr, "increment past of ConstStrBlobPtr");
++curr;
return *this;
}
template<typename T>
StrBlob<T>::StrBlob() :data(data(std::make_shared<std::vector<int>>)) {}
template<typename T>
StrBlob<T>::StrBlob(std::initializer_list<T>il) : data(std::make_shared<std::vector<T>>(il)) {}
template <typename T>
void StrBlob<T>::check(size_type i, const T& msg)const
{
if (i >= data->size())
throw std::out_of_range(msg);
}
template<typename T>
T& StrBlob<T>::front()
{
check(0, "front on empty StrBlob");
return data->front();
}
template<typename T>
T& StrBlob<T>::back()
{
check(0, "back on empty set");
return data->back();
}
template<typename T>
const T& StrBlob<T>::front() const
{
check(0, "front on empty StrBlob");
return data->front();
}
template<typename T>
const T& StrBlob<T>::back() const
{
check(0, "back on empty set");
return data->back();
}
template<typename T>
void StrBlob<T>::pop_back()
{
check(0, "pop_back on empty StrBlob");
data->pop_back();
}
template<typename T>
ConstStrBlobPtr<T>StrBlob<T>::begin() { return ConstStrBlobPtr<T>*this; }
template<typename T>
ConstStrBlobPtr<T> StrBlob<T>::end()
{
auto ret = ConstStrBlobPtr<T>(*this, data->size());
return ret;
}
#endif // !STRBLOB_H_
Screen.h
#ifndef SCREEN_H_
#define SCREEN_H_
#include<vector>
#include<string>
template<unsigned W,unsigned H>
class Screen
{
public:
using pos = std::string::size_type;
Screen() = default;
Screen(char c) :contents(H*W,c) {}
Screen& move(pos r, pos c);
Screen& set(char);
Screen& set(pos, pos, char);
const Screen& display(std::ostream& os)const { do_display(os); return *this; }
private:
pos cusor = 0;
pos height = H, width = W;
std::string contents;
void do_display(std::ostream& os) const { os << contents; }
};
template<unsigned W,unsigned H>
inline Screen<W, H>& Screen<W, H>::move(pos r, pos c)
{
pos row = r * width;
cusor = row + c;
return *this;
}
template<unsigned W, unsigned H>
inline Screen <W, H>& Screen<W, H>::set(char c)
{
contents[cusor] = c;
return *this;
}
template<unsigned W,unsigned H>
inline Screen <W, H>& Screen<W, H>::set(pos r, pos col, char c)
{
contents[r * width + col] = c;
return *this;
}
#endif // !SCREEN_H
main.cpp
#include<iostream>
#include<string>
#include"Screen.h"
int main()
{
Screen<5, 5> myScreen('X');
myScreen.move(4, 0).set('#').display(std::cout);
std::cout << "\n";
myScreen.display(std::cout);
std::cout << "\n";
}
Screen.h
#ifndef SCREEN_H_
#define SCREEN_H_
#include<vector>
#include<string>
template<unsigned W,unsigned H>
class Screen
{
public:
using pos = std::string::size_type;
friend std::ostream& operator<<(std::ostream& os, const Screen <H, W>& c)
{
unsigned int i, j;
for (i = 0; i < c.height; ++i)
{
os << c.contents.substr(i * W, W) << std::endl;
}
return os;
}
friend std::istream& operator>>(std::istream& is, Screen& c)
{
char a;
is >> a;
std::string tmp(H * W, a);
c.contents = tmp;
return is;
}
Screen() = default;
Screen(char c) :contents(H*W,c) {}
char get()const { return contents[cursor]; }
char get(pos r, pos c)const { return contents[r * width + c]; }
Screen& move(pos r, pos c);
Screen& set(char);
Screen& set(pos, pos, char);
Screen& display(std::ostream& os) { do_display(os); return *this; }
const Screen& display(std::ostream& os)const { do_display(os); return *this; }
private:
pos cursor = 0;
pos height = H, width = W;
std::string contents;
void do_display(std::ostream& os) const { os << contents; }
};
template<unsigned W,unsigned H>
inline Screen<W, H>& Screen<W, H>::move(pos r, pos c)
{
pos row = r * width;
cursor = row + c;
return *this;
}
template<unsigned W, unsigned H>
inline Screen <W, H>& Screen<W, H>::set(char c)
{
contents[cursor] = c;
return *this;
}
template<unsigned W,unsigned H>
inline Screen <W, H>& Screen<W, H>::set(pos r, pos col, char c)
{
contents[r * width + col] = c;
return *this;
}
#endif // !SCREEN_H
main.cpp
#include<iostream>
#include<string>
#include"Screen.h"
int main()
{
Screen<5, 5> myScreen('X');
myScreen.move(4, 0).set('#').display(std::cout);
std::cout << "\n";
myScreen.display(std::cout);
std::cout << "\n";
std::cout << myScreen << std::endl;
}
Vec.h
#ifndef VEC_H_
#define VEC_H_
#include <string>
#include <utility>
#include <memory>
#include <algorithm>
template <typename T>
class Vec;
template <typename T>
bool operator==(Vec<T>& lhs, Vec<T>& rhs);
template <typename T>
bool operator!=(Vec<T>& lhs, Vec<T>& rhs);
template <typename T>
bool operator<(Vec<T>& lhs, Vec<T>& rhs);
template <typename T>
bool operator>(Vec<T>& lhs, Vec<T>& rhs);
template <typename T>
bool operator<=(Vec<T>& lhs, Vec<T>& rhs);
template <typename T>
bool operator>=(Vec<T>& lhs, Vec<T>& rhs);
template <typename T>
class Vec
{
friend bool operator== <T> (Vec& lhs, Vec& rhs);
friend bool operator!= <T> (Vec& lhs, Vec& rhs);
friend bool operator< <T> (Vec& lhs, Vec& rhs);
friend bool operator> <T> (Vec& lhs, Vec& rhs);
friend bool operator<= <T> (Vec& lhs, Vec& rhs);
friend bool operator>= <T> (Vec& lhs, Vec& rhs);
public:
Vec() : elements(nullptr), first_free(nullptr), cap(nullptr) { }
Vec(std::initializer_list<T>);
Vec(const Vec&);
Vec(Vec&& s) noexcept : alloc(std::move(s.alloc)), elements(std::move(s.elements)), first_free(std::move(s.first_free)), cap(std::move(s.cap)) { s.elements = s.first_free = s.cap = nullptr; }
Vec& operator=(const Vec&);
Vec& operator=(Vec&&) noexcept;
T& operator[](std::size_t n) { return elements[n]; }
const T& operator[](std::size_t n) const { return elements[n]; }
~Vec();
void push_back(const T&);
size_t size() const { return first_free - elements; }
size_t capacity() const { return cap - elements; }
T* begin() const { return elements; }
T* end() const { return first_free; }
void reserve(size_t n);
void resize(size_t n);
void resize(size_t n, const T& s);
private:
std::allocator<T> alloc;
void chk_n_alloc() { if (size() == capacity()) reallocate(); }
std::pair<T*, T*> alloc_n_copy(const T*, const T*);
void free();
void reallocate();
T* elements;
T* first_free;
T* cap;
};
template <typename T>
Vec<T>::Vec(std::initializer_list<T> il)
{
auto newdata = alloc_n_copy(il.begin(), il.end());
elements = newdata.first;
first_free = cap = newdata.second;
}
template <typename T>
void Vec<T>::push_back(const T& s)
{
chk_n_alloc();
alloc.construct(first_free++, s);
}
template <typename T>
std::pair<T*, T*> Vec<T>::alloc_n_copy(const T* b, const T* e)
{
auto data = alloc.allocate(e - b);
return { data, uninitialized_copy(b, e, data) };
}
template <typename T>
void Vec<T>::free()
{
if (elements)
{
std::for_each(elements, first_free, [this](T& p) { alloc.destroy(&p); });
// for(auto p = first_free; p != elements; )
// alloc.destroy(--p);
alloc.deallocate(elements, cap - elements);
}
}
template <typename T>
Vec<T>::Vec(const Vec<T>& s)
{
auto newdata = alloc_n_copy(s.begin(), s.end());
elements = newdata.first;
first_free = cap = newdata.second;
}
template <typename T>
Vec<T>::~Vec()
{
free();
}
template <typename T>
void Vec<T>::reserve(size_t n)
{
if (n > capacity()) return;
auto newdata = alloc.allocate(n);
auto dest = newdata;
auto elem = elements;
for (size_t i = 0; i != size(); ++i)
alloc.construct(dest++, std::move(*elem++));
free();
elements = newdata;
first_free = dest;
cap = elements + n;
}
template <typename T>
void Vec<T>::resize(size_t n)
{
resize(n, T());
}
template <typename T>
void Vec<T>::resize(size_t n, const T& s)
{
if (n < size())
{
while (n < size())
alloc.destroy(--first_free);
}
else if (n > size())
{
while (n > size())
push_back(s);
// alloc.construct(first_free, s);
}
}
template <typename T>
Vec<T>& Vec<T>::operator=(const Vec<T>& rhs)
{
auto data = alloc_n_copy(rhs.begin(), rhs.end());
free();
elements = data.first;
first_free = cap = data.second;
return *this;
}
template <typename T>
Vec<T>& Vec<T>::operator=(Vec<T>&& rhs) noexcept
{
if (this != &rhs)
{
free();
alloc = std::move(rhs.alloc);
elements = std::move(rhs.elements);
first_free = std::move(rhs.first_free);
cap = std::move(rhs.cap);
rhs.elements = rhs.first_free = rhs.cap = nullptr;
}
return *this;
}
template <typename T>
void Vec<T>::reallocate()
{
auto newcapacity = size() ? 2 * size() : 1;
auto newdata = alloc.allocate(newcapacity);
auto dest = newdata;
auto elem = elements;
for (size_t i = 0; i != size(); ++i)
alloc.construct(dest++, std::move(*elem++));
free();
elements = newdata;
first_free = dest;
cap = elements + newcapacity;
}
template <typename T>
bool operator==(Vec<T>& lhs, Vec<T>& rhs)
{
return lhs.size() == rhs.size() && std::equal(lhs.begin(), lhs.end(), rhs.begin());
}
template <typename T>
bool operator!=(Vec<T>& lhs, Vec<T>& rhs)
{
return !(lhs == rhs);
}
template <typename T>
bool operator<(Vec<T>& lhs, Vec<T>& rhs)
{
return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
}
template <typename T>
bool operator>(Vec<T>& lhs, Vec<T>& rhs)
{
return rhs < lhs;
}
template <typename T>
bool operator<=(Vec<T>& lhs, Vec<T>& rhs)
{
return !(rhs < lhs);
}
template <typename T>
bool operator>=(Vec<T>& lhs, Vec<T>& rhs)
{
return !(lhs < rhs);
}
#endif
main.cpp
#include"Vec.h"
#include<string>
int main()
{
Vec<std::string> s({ "aaa","bbb" });
return 0;
}
#include<iostream>
#include<string>
#include<vector>
template<typename T>
void print_vector(T& v)
{
for (typename T::size_type i = 0; i != v.size(); ++i)
std::cout << v[i]<<" ";
std::cout << std::endl;
}
int main()
{
std::vector<std::string>vs = {"a","bb","ccc"};
print_vector(vs);
std::vector<int>vi = { 1,2,3,4,5 };
print_vector(vi);
return 0;
}
#include<iostream>
#include<string>
#include<vector>
template<typename T>
void print_vector(T& v)
{
for (typename T::size_type i = 0; i != v.size(); ++i)
std::cout << v[i]<<" ";
std::cout << std::endl;
}
template<typename T>
void print_vector2(T& v)
{
for(typename T::iterator iter=v.begin();iter!=v.end();++iter)
std::cout << *iter << " ";
std::cout << std::endl;
}
int main()
{
std::vector<std::string>vs = {"a","bb","ccc"};
print_vector(vs);
print_vector2(vs);
std::vector<int>vi = { 1,2,3,4,5 };
print_vector(vi);
print_vector2(vi);
return 0;
}
#include<iostream>
class DebugDelete
{
public:
DebugDelete(std::ostream& s = std::cerr) :os(s) {};
template <typename T> void operator()(T* p)const
{
os << "deleting unique_ptr" << std::endl;
delete p;
}
private:
std::ostream& os;
};
int main()
{
int* p = new int;
DebugDelete d;
d(p);
return 0;
}
#ifndef TEXTQUERY_H_
#define TEXTQUERY_H_
#include <string>
#include <vector>
#include <map>
#include <fstream>
#include <sstream>
#include <set>
#include <memory>
#include <iostream>
#include <algorithm>
#include <iterator>
#include "StrBlob.h"
#include "DebugDelete.h"
class QueryResult;
class TextQuery
{
public:
using line_no = std::vector<std::string>::size_type;
TextQuery(std::ifstream&);
QueryResult query(const std::string&) const;
private:
StrBlob file;
std::map<std::string, std::shared_ptr<std::set<line_no>>> word_map;
};
class QueryResult
{
friend std::ostream& print(std::ostream&, const QueryResult&);
public:
QueryResult(std::string s, std::shared_ptr<std::set<TextQuery::line_no>> p, StrBlob f) : sought(s), lines(p), file(f) { }
std::set<StrBlob::size_type>::iterator begin() const { return lines->begin(); }
std::set<StrBlob::size_type>::iterator end() const { return lines->end(); }
// std::shared_ptr<StrBlob> get_file() const { return std::make_shared<StrBlob>(file); }
const StrBlob& get_file() const { return file; }
private:
std::string sought;
std::shared_ptr<std::set<TextQuery::line_no>> lines;
StrBlob file;
};
TextQuery::TextQuery(std::ifstream &ifs)
{
std::string text_line;
while(std::getline(ifs, text_line))
{
file.push_back(text_line);
int line_number = file.size() - 1;
std::istringstream line(text_line);
std::string text_word;
while(line >> text_word)
{
std::string word;
std::copy_if(text_word.begin(), text_word.end(), std::back_inserter(word), isalpha);
// std::cout << word << std::endl;
auto &wm_lines = word_map[word];
if(!wm_lines)
wm_lines.reset(new std::set<line_no>, DebugDelete());
wm_lines->insert(line_number);
}
}
}
QueryResult TextQuery::query(const std::string &sought) const
{
static std::shared_ptr<std::set<TextQuery::line_no>> nodata(new std::set<TextQuery::line_no>);
auto loc = word_map.find(sought);
if(loc == word_map.end())
return QueryResult(sought, nodata, file);
else
return QueryResult(sought, loc->second, file);
}
std::ostream &print(std::ostream &os, const QueryResult &qr)
{
os << qr.sought << " occurs " << qr.lines->size() << " " /*<< make_plural(qr.lines->size(), "time", "s")*/ << std::endl;
for(auto num : *qr.lines)
{
ConstStrBlobPtr p(qr.file, num);
os << "\t(line " << num + 1 << ") " << p.deref() << std::endl;
}
return os;
}
#endif
#ifndef BLOB_H_
#define BLOB_H_
#include<vector>
#include<memory>
template<typename T>
class Blob
{
template<typename It>
Blob(It begin, It end);
private:
std::shared_ptr<std::vector<T>> data;
};
template<typename T>
template<typename It>
Blob<T>::Blob(It begin, It end) :data(std::make_shared<std::vector<T>>(begin,end)) {};
#endif // !BLOB_H_
shared_pointer.h
#pragma once
#include<functional>
#include"deleter.h"
namespace cp5
{
template<typename T>
class SharedPointer;
template<typename T>
void swap(SharedPointer<T>& lhs, SharedPointer<T>& rhs)
{
using std::swap;
swap(lhs.ptr, rhs.ptr);
swap(lhs.ref_count, rhs.count);
swap(lhs.deleter, rhs.deleter);
}
template<typename T>
class SharedPointer
{
public:
SharedPointer() :ptr(nullptr), ref_count(new std::size_t(1)), deleter{ cp5::Delete{} } {}
explicit SharedPointer(T* raw_ptr) :ptr(raw_ptr), ref_count(new std::size_t(1)),
deleter{ cp5::Delete{} } {}
SharedPointer(SharedPointer const& other) :ptr{ other.ptr }, ref_count{ other.ref_count },
deleter{ other.deleter } {++* ref_count; }
SharedPointer(SharedPointer&& other)noexcept :ptr{ other.ptr }, ref_count{ other.ref_count },
deleter{std::move(other.deleter)} {}
SharedPointer& operator==(SharedPointer const& rhs)
{
++* rhs.ref_count;
decrement_and_destory();
ptr = rhs.ptr, ref = rhs.ref_count, deleter = rhs.deleter;
return *this;
}
SharedPointer& operator=(SharedPointer&& rhs)noexcept
{
cp5::swap(*this, rhs);
rhs.decrement_and_destory();
return *this;
}
operator bool()const
{
return ptr ? true : false;
}
T& operator*()const
{
return *ptr;
}
T* operator->()const
{
return &*ptr;
}
std::size_t use_count()const
{
return *ref_count;
}
T* get()const
{
return ptr;
}
bool unique()const
{
return 1 == *ref_count;
}
void swap(SharedPointer& rhs)
{
cp5::swap(*this, rhs);
}
void reset()
{
decrement_and_destory();
}
void reset(T* pointer, const std::function<void(T*)>& d)
{
reset(pointer);
deleter = d;
}
~SharedPointer()
{
decrement_and_destory();
}
private:
T* ptr;
std::size_type* ref_count;
std::function<void(T*)>deleter;
void decrement_and_destory()
{
if (ptr && 0 == -- * ref_count)
delete ref_count, deleter(ptr);
else if (!ptr)
delete ref_count;
ref_count = nullptr;
ptr = nullptr;
}
};
}
unique_ptr.h
#ifndef UNIQUE_POINTER_H
#define UNIQUE_POINTER_H
template<typename, typename>class unique_pointer;
template<typename T, typename D>void
swap(unique_pointer<T, D>& lhs, unique_pointer<T, D>& rhs);
template<typename T,typename D=DebugDelete>
class unique_pointer
{
friend void swap(unique_pointer<T, D>& lhs, unique_pointer<T, D>& rhs);
public:
unique_pointer(const unique_pointer&) = delete;
unique_pointer& operator=(const unique_pointer&) = delete;
unique_pointer() = default;
explicit unique_pointer(T* up) :ptr(up) {}
unique_pointer(unique_pointer&& up)noexcept :ptr(up.ptr) { up.ptr = nullptr; }
unique_pointer& operator=(unique_pointer&& up)noexcept;
unique_pointer operator=(std::nullptr_t n)noexcept;
T& operator*()const { return *ptr; }
T* operator->()const { return &this->operator*(); }
operator bool()const { return ptr ? true : false; }
T* get()const noexcept { return ptr; }
void swap(unique_pointer<T, D>& rhs) { ::swap(*this, rhs); }
void reset()noexcept { deleter(ptr); ptr = nullptr; }
void rest(T* p)noexcept { deleter(ptr); ptr = p; }
T* release();
~unique_pointer()
{
deleter(ptr);
}
private:
T* ptr = nullptr;
D deleter = D();
};
template<typename T,typename D>
inline void swap(unique_pointer<T, D>& lhs, unique_pointer<T, D>& rhs)
{
using std::swap;
swap(lhs.ptr, rhs.ptr);
swap(lhs.deleter, rhs.deleter);
}
template<typename T, typename D>
inline unique_pointer <T, D>& unique_pointer<T, D>::operator=(unique_pointer&& rhs)noexcept
{
if (this->ptr!rhs.ptr)
{
delete(ptr);
ptr = nullptr;
::swap(*this, rhs);
}
return *this;
}
template<typename T, typename D>
inline unique_pointer<T, D>& unique_pointer<T, D>::operator=(std::nullptr_t n)noexcept
{
if (n == nullptr)
{
delete(ptr);
ptr = nullptr;
}
return *this;
}
template<typename T, typename D>
inline T* unique_pointer<T, D>::release()
{
T* ret = ptr;
ptr = nullptr;
return ret;
}
#endif // !UNIQUE_POINTER_H
#ifndef BLOB_H_
#define BLOB_H_
#include <vector>
#include <memory>
#include "shared_pointer.h"
template <typename T>
class Blob
{
public:
// template <typename It>
// Blob(It begin, It end) : data(std::make_shared<std::vector<T>>(begin, end)) { }
template <typename It>
Blob(It begin, It end);
private:
cp5::shared_pointer<std::vector<T>> data;
};
template <typename T>
template <typename It>
Blob<T>::Blob(It begin, It end) : data(std::make_shared<std::vector<T>>(begin, end)) { }
#endif
#include <iostream>
template <typename T>
auto sum(T lhs, T rhs) -> decltype(lhs + rhs)
{
return lhs + rhs;
}
int main()
{
auto s = sum(123456789123456789123456, 123456789123456789123456);
return 0;
}
#include<iostream>
#include<memory>
void func_lvalue(std::string& lhs, std::string& rhs)
{
lhs = "gao\n";
rhs = "xu\n";
}
void func_rvalue(int&& lhs, int&& rhs)
{
//allocate enough space
std::allocator<int> alloc;
int* data(alloc.allocate(3));
//move into the space newly allocated
alloc.construct(data, lhs);
alloc.construct(data + 1, 0);
alloc.construct(data + 2, rhs);
//print
for (auto p = data; p != data + 3; ++p)
std::cout << *p << "\n";
//destory and deallocation
for (auto p = data + 3; p != data;)
alloc.destroy(--p);
alloc.deallocate(data, 3);
}
template<typename F,typename T1,typename T2>
void flip(F f, T1&& t1, T2&& t2)
{
f(std::forward<T2>(t2), std::forward<T1>(t1));
}
int main()
{
//test for lvalue reference
std::string s1, s2;
flip(func_lvalue, s1, s2);
std::cout << s1 << s2;
//test for rvalue reference
flip(func_rvalue, 99, 88);
return 0;
}
#include<iostream>
template <typename T>
void f(T t)
{
std::cout << "template <typename T> void f(T t)" << std::endl;
}
template <typename T>
void f(const T* t)
{
std::cout << "template <typename T> void f(const T*t)" << std::endl;
}
template <typename T>
void g(T t)
{
std::cout << "template <typename T> void g(T t)" << std::endl;
}
template <typename T>
void g(const T* t)
{
std::cout << "template <typename T> void g(const T*t)" << std::endl;
}
int main()
{
int i = 42, * p = &i;
const int ci = 0, * pi = &ci;
g(42);
g(p);
g(ci);
g(pi);
f(42);
f(p);
f(ci);
f(pi);
return 0;
}
#include <iostream>
template <typename T>
void f(T t)
{
std::cout << "template <typename T> void f(T t)" << std::endl;
}
template <typename T>
void f(const T* t)
{
std::cout << "template <typename T> void f(const T *t)" << std::endl;
}
template <typename T>
void g(T t)
{
std::cout << "template <typename T> void g(T t)" << std::endl;
}
template <typename T>
void g(T* t)
{
std::cout << "template <typename T> void g(T *t)" << std::endl;
}
int main()
{
int i = 42, * p = &i;
const int ci = 0, * p2 = &ci;
g(42);
g(p);
g(ci);
g(p2);
f(42);
f(p);
f(ci);
f(p2);
return 0;
}
#include<iostream>
template<typename T,typename ...Args>
void Foo(const T& t, const Args&...rest)
{
std::cout << sizeof...(Args) << std::endl;
std::cout << sizeof...(rest) << std::endl;
}
int main()
{
int i = 0;
double d = 3.14;
std::string s = "how are you";
Foo(i, s, 42, d);
Foo(s, 42, d);
Foo(d, s);
Foo("hi");
return 0;
}
#include<iostream>
#include<string>
template<typename T>
std::ostream& print(std::ostream& os, const T& t)
{
os << t;
return os;
}
template<typename T,typename ...Args>
std::ostream& print(std::ostream& os, const T& t, const Args&...rest)
{
os << t<<", ";
return print(os, rest...);
}
int main()
{
int i=1, * p = &i;
double d = 0.1;
std::string s = "aaa";
print(std::cout, i);
std::cout << std::endl;
print(std::cout, i, d);
std::cout << std::endl;
print(std::cout, i, d, s, p, "bbb");
std::cout << std::endl;
return 0;
}
#include<iostream>
#include<memory>
#include<sstream>
template <typename T>std::string debug_rep(const T& t);
template <typename T>std::string debug_rep(T* p);
std::string debug_rep(const std::string& s);
std::string debug_rep(char* p);
std::string debug_rep(const char* p);
template <typename T>
std::string debug_rep(const T& t)
{
std::ostringstream ret;
ret << t;
return ret.str();
}
template <typename T>
std::string debug_rep(const T *p)
{
std::ostringstream ret;
ret << "pointer:"<<p;
if (p)
ret << " " << debug_rep(*p);
else
ret << "null pointer";
return ret.str();
}
std::string debug_rep(const std::string& s)
{
return '"' + s + '"';
}
std::string debug_rep(char *p)
{
return debug_rep(std::string(p));
}
std::string debug_rep(const char* p)
{
std::cout <<"debug_rep(const char* p)" << std::endl;
return debug_rep(std::string(p));
}
template<typename T>
std::ostream& print(std::ostream& os, const T& t)
{
os << t << " ,";
return os;
}
template<typename T,typename ...Args>
std::ostream& print(std::ostream& os, const T& t, const Args&...rest)
{
os << t << ",";
return print(os, rest...);
}
template<typename ...Args>
std::ostream& errorMsg(std::ostream& os, const Args&...rest)
{
return print(os, debug_rep(rest)...);
}
int main()
{
std::string s = "aaa";
errorMsg(std::cout, 1, 4, "b", s);
return 0;
}
#ifndef STRVEC_H_
#define STRVEC_H_
#include <string>
#include <utility>
#include <memory>
#include <algorithm>
class StrVec
{
friend bool operator==(StrVec &lhs, StrVec &rhs);
friend bool operator!=(StrVec &lhs, StrVec &rhs);
friend bool operator<(StrVec &lhs, StrVec &rhs);
friend bool operator>(StrVec &lhs, StrVec &rhs);
friend bool operator<=(StrVec &lhs, StrVec &rhs);
friend bool operator>=(StrVec &lhs, StrVec &rhs);
public:
StrVec() : elements(nullptr), first_free(nullptr), cap(nullptr) { }
StrVec(std::initializer_list<std::string>);
StrVec(const StrVec&);
StrVec(StrVec &&s) noexcept : alloc(std::move(s.alloc)), elements(std::move(s.elements)), first_free(std::move(s.first_free)), cap(std::move(s.cap)) { s.elements = s.first_free = s.cap = nullptr; }
template <typename... Args>
void emplace_back(Args&&... args);
StrVec &operator=(const StrVec&);
StrVec &operator=(StrVec&&) noexcept;
std::string& operator[](std::size_t n) { return elements[n]; }
const std::string& operator[](std::size_t n) const { return elements[n]; }
~StrVec();
void push_back(const std::string&);
size_t size() const { return first_free - elements; }
size_t capacity() const { return cap - elements; }
std::string *begin() const { return elements; }
std::string *end() const { return first_free; }
void reserve(size_t n);
void resize(size_t n);
void resize(size_t n, const std::string &s);
private:
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;
};
StrVec::StrVec(std::initializer_list<std::string> il)
{
auto newdata = alloc_n_copy(il.begin(), il.end());
elements = newdata.first;
first_free = cap = newdata.second;
}
template <typename... Args>
inline void StrVec::emplace_back(Args&&... args)
{
chk_n_alloc();
alloc.construct(first_free++, std::forward<Args>(args)...);
}
void StrVec::push_back(const std::string &s)
{
chk_n_alloc();
alloc.construct(first_free++, s);
}
std::pair<std::string*,std::string*> StrVec::alloc_n_copy(const std::string *b, const std::string *e)
{
auto data = alloc.allocate(e-b);
return {data, uninitialized_copy(b, e, data)};
}
void StrVec::free()
{
if(elements)
{
std::for_each(elements, first_free, [this](std::string &p){ alloc.destroy(&p); });
// for(auto p = first_free; p != elements; )
// alloc.destroy(--p);
alloc.deallocate(elements, cap-elements);
}
}
StrVec::StrVec(const StrVec &s)
{
auto newdata = alloc_n_copy(s.begin(), s.end());
elements = newdata.first;
first_free = cap = newdata.second;
}
StrVec::~StrVec()
{
free();
}
void StrVec::reserve(size_t n)
{
if(n > capacity()) return;
auto newdata = alloc.allocate(n);
auto dest = newdata;
auto elem = elements;
for(size_t i = 0; i != size(); ++i)
alloc.construct(dest++, std::move(*elem++));
free();
elements = newdata;
first_free = dest;
cap = elements + n;
}
void StrVec::resize(size_t n)
{
resize(n,std::string());
}
void StrVec::resize(size_t n, const std::string &s)
{
if(n < size())
{
while(n < size())
alloc.destroy(--first_free);
}else if(n > size())
{
while(n > size())
push_back(s);
// alloc.construct(first_free, s);
}
}
StrVec &StrVec::operator=(const StrVec &rhs)
{
auto data = alloc_n_copy(rhs.begin(), rhs.end());
free();
elements = data.first;
first_free = cap = data.second;
return *this;
}
StrVec &StrVec::operator=(StrVec &&rhs) noexcept
{
if(this != &rhs)
{
free();
alloc = std::move(rhs.alloc);
elements = std::move(rhs.elements);
first_free = std::move(rhs.first_free);
cap = std::move(rhs.cap);
rhs.elements = rhs.first_free = rhs.cap = nullptr;
}
return *this;
}
void StrVec::reallocate()
{
auto newcapacity = size() ? 2 * size() : 1;
auto newdata = alloc.allocate(newcapacity);
auto dest = newdata;
auto elem = elements;
for(size_t i = 0; i != size(); ++i)
alloc.construct(dest++, std::move(*elem++));
free();
elements = newdata;
first_free = dest;
cap = elements + newcapacity;
}
bool operator==(StrVec &lhs, StrVec &rhs)
{
return lhs.size() == rhs.size() && std::equal(lhs.begin(), lhs.end(), rhs.begin());
}
bool operator!=(StrVec &lhs, StrVec &rhs)
{
return !(lhs == rhs);
}
bool operator<(StrVec &lhs, StrVec &rhs)
{
return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
}
bool operator>(StrVec &lhs, StrVec &rhs)
{
return rhs < lhs;
}
bool operator<=(StrVec &lhs, StrVec &rhs)
{
return !(rhs < lhs);
}
bool operator>=(StrVec &lhs, StrVec &rhs)
{
return !(lhs < rhs);
}
#endif
#include<iostream>
#include<memory>
namespace ch16
{
template <typename T,typename ...Args>
std::shared_ptr<T> make_shared(Args&& ...args)
{
return std::shared_ptr<T>(new T(std::forward<Args>(args)...));
}
}
int main()
{
auto sp1 = ch16::make_shared<int>(1);
std::cout << *sp1 << std::endl;
auto str = ch16::make_shared<std::string>(10, 'c');
std::cout << *str << std::endl;
return 0;
}
Sales_data.h
#ifndef SALES_DATA_H_
#define SALES_DATA_H_
#include <string>
struct Sales_data;
std::istream &operator>>(std::istream &is, Sales_data &item);
std::ostream &operator<<(std::ostream &os, const Sales_data &item);
Sales_data operator+(const Sales_data &lhs, const Sales_data &rhs);
struct Sales_data
{
friend std::istream& operator>>(std::istream&, Sales_data&);
friend std::ostream& operator<<(std::ostream&, const Sales_data&);
friend Sales_data operator+(const Sales_data&, const Sales_data&);
friend bool operator==(const Sales_data&, const Sales_data&);
friend class std::hash<Sales_data>;
public:
Sales_data(const std::string &s, unsigned n, double p) : bookNo(s), units_sold(n), revenue(p*n){std::cout << "Sales_data(const std::string &s, unsigned n, double p)" << std::endl;}
Sales_data() : Sales_data("", 0, 0){std::cout << "Sales_data() : Sales_data(\"\", 0, 0)" << std::endl;}
Sales_data(const std::string &s) : Sales_data(s, 0, 0){std::cout << "Sales_data(const std::string &s) : Sales_data" << std::endl;}
Sales_data(std::istream &is) : Sales_data(){/*read(is, *this);*/ is >> *this; std::cout << "Sales_data(std::istream &is) : Sales_data()" << std::endl;}
std::string isbn() const {return bookNo;}
Sales_data& operator=(const std::string&);
Sales_data& operator+=(const Sales_data&);
Sales_data& operator-=(const Sales_data&);
private:
inline double avg_price() const;
std::string bookNo;
unsigned units_sold = 0;
double revenue = 0.0;
};
inline double Sales_data::avg_price() const
{
if(units_sold)
return revenue / units_sold;
else
return 0;
}
Sales_data& Sales_data::operator=(const std::string &s)
{
*this = Sales_data(s);
return *this;
}
Sales_data& Sales_data::operator+=(const Sales_data &rhs)
{
units_sold += rhs.units_sold;
revenue += rhs.revenue;
return *this;
}
Sales_data& Sales_data::operator-=(const Sales_data &rhs)
{
units_sold -= rhs.units_sold;
revenue -= rhs.revenue;
return *this;
}
std::istream &operator>>(std::istream &is, Sales_data &item)
{
double price = 0;
is >> item.bookNo >> item.units_sold >> price;
if(is)
item.revenue = price * item.units_sold;
else
item = Sales_data();
return is;
}
std::ostream &operator<<(std::ostream &os, const Sales_data &item)
{
os << item.isbn() << " " << item.units_sold << " " << item.revenue << " " << item.avg_price();
return os;
}
Sales_data operator+(const Sales_data &lhs, const Sales_data &rhs)
{
Sales_data sum = lhs;
sum += rhs;
return sum;
}
bool operator==(const Sales_data &lhs, const Sales_data &rhs)
{
return lhs.isbn() == rhs.isbn() &&
lhs.units_sold == rhs.units_sold &&
lhs.revenue == rhs.revenue;
}
#endif
ex62.cpp
#ifndef SALES_DATA_H_
#define SALES_DATA_H_
#include <string>
struct Sales_data;
std::istream &operator>>(std::istream &is, Sales_data &item);
std::ostream &operator<<(std::ostream &os, const Sales_data &item);
Sales_data operator+(const Sales_data &lhs, const Sales_data &rhs);
struct Sales_data
{
friend std::istream& operator>>(std::istream&, Sales_data&);
friend std::ostream& operator<<(std::ostream&, const Sales_data&);
friend Sales_data operator+(const Sales_data&, const Sales_data&);
friend bool operator==(const Sales_data&, const Sales_data&);
friend class std::hash<Sales_data>;
public:
Sales_data(const std::string &s, unsigned n, double p) : bookNo(s), units_sold(n), revenue(p*n){std::cout << "Sales_data(const std::string &s, unsigned n, double p)" << std::endl;}
Sales_data() : Sales_data("", 0, 0){std::cout << "Sales_data() : Sales_data(\"\", 0, 0)" << std::endl;}
Sales_data(const std::string &s) : Sales_data(s, 0, 0){std::cout << "Sales_data(const std::string &s) : Sales_data" << std::endl;}
Sales_data(std::istream &is) : Sales_data(){/*read(is, *this);*/ is >> *this; std::cout << "Sales_data(std::istream &is) : Sales_data()" << std::endl;}
std::string isbn() const {return bookNo;}
Sales_data& operator=(const std::string&);
Sales_data& operator+=(const Sales_data&);
Sales_data& operator-=(const Sales_data&);
private:
inline double avg_price() const;
std::string bookNo;
unsigned units_sold = 0;
double revenue = 0.0;
};
inline double Sales_data::avg_price() const
{
if(units_sold)
return revenue / units_sold;
else
return 0;
}
Sales_data& Sales_data::operator=(const std::string &s)
{
*this = Sales_data(s);
return *this;
}
Sales_data& Sales_data::operator+=(const Sales_data &rhs)
{
units_sold += rhs.units_sold;
revenue += rhs.revenue;
return *this;
}
Sales_data& Sales_data::operator-=(const Sales_data &rhs)
{
units_sold -= rhs.units_sold;
revenue -= rhs.revenue;
return *this;
}
std::istream &operator>>(std::istream &is, Sales_data &item)
{
double price = 0;
is >> item.bookNo >> item.units_sold >> price;
if(is)
item.revenue = price * item.units_sold;
else
item = Sales_data();
return is;
}
std::ostream &operator<<(std::ostream &os, const Sales_data &item)
{
os << item.isbn() << " " << item.units_sold << " " << item.revenue << " " << item.avg_price();
return os;
}
Sales_data operator+(const Sales_data &lhs, const Sales_data &rhs)
{
Sales_data sum = lhs;
sum += rhs;
return sum;
}
bool operator==(const Sales_data &lhs, const Sales_data &rhs)
{
return lhs.isbn() == rhs.isbn() &&
lhs.units_sold == rhs.units_sold &&
lhs.revenue == rhs.revenue;
}
#endif
#include<iostream>
#include<vector>
#include<algorithm>
template<typename T>
size_t get_number(T t, std::vector<T> const& vt)
{
size_t n = 0;
auto iter = vt.begin();
do
{
iter = std::find(iter, vt.end(), t);
if (iter != vt.end())
{
++n;
++iter;
}
} while (iter!=vt.end());
return n;
}
size_t get_number(const char *p, std::vector<std::string> const& vt)
{
size_t n = 0;
auto iter = vt.begin();
std::string s(p);
do
{
iter = std::find(iter, vt.end(), s);
if (iter != vt.end())
{
++n;
++iter;
}
} while (iter != vt.end());
return n;
}
template<>
size_t get_number(const char* p, std::vector<const char*> const& vt)
{
size_t n = 0;
auto iter = vt.begin();
std::string s(p);
do
{
iter = std::find(iter, vt.end(), s);
if (iter != vt.end())
{
++n;
++iter;
}
} while (iter != vt.end());
return n;
}
int main()
{
std::vector<double> vd = { 1,2,3.14,4,5 };
std::vector<int> vi = { 1,2,3,4,3,6 };
std::vector<std::string>vs = { "aaa","bbb","ccc" };
std::vector<const char*>vcp = { "a","bb","ccc" };
std::cout << get_number(3.14, vd) << std::endl;
std::cout << get_number(3, vi) << std::endl;;
std::cout << get_number("aaa", vs) << std::endl;
std::cout << get_number("bb", vcp) << std::endl;
return 0;
}
#include <iostream>
#include <memory>
#include <sstream>
template <typename T> std::string debug_rep(const T& t);
template <typename T> std::string debug_rep(T* p);
std::string debug_rep(const std::string& s);
template <typename T>
std::string debug_rep(const T& t)
{
std::ostringstream ret;
ret << t;
return ret.str();
}
template <typename T>
std::string debug_rep(T* p)
{
std::ostringstream ret;
ret << "pointer: " << p;
if (p)
ret << " " << debug_rep(*p);
else
ret << " null pointer";
return ret.str();
}
std::string debug_rep(const std::string& s)
{
return '"' + s + '"';
}
template<>
std::string debug_rep(char* p)
{
return debug_rep(std::string(p));
}
template<>
std::string debug_rep(const char*p)
{
std::cout << "string debug_rep(const char*)" << std::endl;
return debug_rep(std::string(p));
}
int main()
{
char ca[] = { 'a', 'b', 'c', '\0' };
std::cout << debug_rep(ca) << std::endl;
return 0;
}