提交 dc5c2114 编写于 作者: J jzplp

16.53-16.67

上级 ff19589c
#include<iostream>
#include<string>
template <typename T>
std::ostream & print(std::ostream & os, const T & t)
{
return os << t;
}
template <typename T, typename ... Args>
std::ostream & print(std::ostream & os, const T & t, const Args & ... rest)
{
os << t << ", ";
return print(os, rest...);
}
int main()
{
print(std::cout, 1) << std::endl;
print(std::cout, 1, "123") << std::endl;
print(std::cout, 1, "123", 3.123, std::string("qwert"), -5) << std::endl;
return 0;
}
#include<iostream>
#include<string>
#include<sstream>
template <typename T> std::ostream & print(std::ostream & os, const T & t);
template <typename T, typename ... Args> std::ostream & print(std::ostream & os, const T & t, const Args & ... rest);
template <typename T> std::string debug_rep(const T &t);
template <typename T> std::string debug_rep(T * p);
std::string debug_rep(const std::string &s);
std::string debug_rep(char *p);
std::string debug_rep(const char *p);
template <typename ... Args> std::ostream & errorMsg(std::ostream & os, const Args & ... rest);
template <typename T>
std::ostream & print(std::ostream & os, const T & t)
{
return os << t;
}
template <typename T, typename ... Args>
std::ostream & print(std::ostream & os, const T & t, const Args & ... rest)
{
os << t << ", ";
return print(os, rest...);
}
template <typename T>
std::string debug_rep(const T &t)
{
std::ostringstream ret;
ret << t;
return ret.str();
}
template <typename T>
std::string debug_rep(T * p)
{
std::ostringstream ret;
ret << "pointer: " << p;
if(p)
ret << " " << debug_rep(*p);
else
ret << " null pointer";
return ret.str();
}
std::string debug_rep(const std::string &s)
{
return '"' + s + '"';
}
std::string debug_rep(char *p)
{
return debug_rep(std::string(p));
}
std::string debug_rep(const char *p)
{
return debug_rep(std::string(p));
}
template <typename ... Args>
std::ostream & errorMsg(std::ostream & os, const Args & ... rest)
{
return print(os, debug_rep(rest)...);
}
int main()
{
int i = 3;
errorMsg(std::cout, 1, "123", std::string("qwer"), &i) << std::endl;
errorMsg(std::cout, 1) << std::endl;
return 0;
}
#include<string>
#include<memory>
#include<utility>
#include<algorithm>
#include<utility>
#include<iostream>
#include "StrVec.h"
std::allocator<std::string> StrVec::alloc;
void StrVec::push_back(const std::string &s)
{
chk_n_alloc();
alloc.construct(first_free++, s);
}
void StrVec::push_back(std::string &&s)
{
chk_n_alloc();
alloc.construct(first_free++, std::move(s));
}
std::pair<std::string *, std::string *> StrVec::alloc_n_copy(const std::string *b, const std::string *e)
{
std::string * data = alloc.allocate(e - b);
return {data, std::uninitialized_copy(b, e, data)};
}
void StrVec::free()
{
if(elements)
{
StrVec * th = this;
std::for_each(elements, first_free, [](std::string &s){ alloc.destroy(&s); } );
alloc.deallocate(elements, cap - elements);
}
}
StrVec::StrVec(const StrVec & s)
{
std::pair<std::string *, std::string *> newdata = alloc_n_copy(s.begin(), s.end());
elements = newdata.first;
first_free = cap = newdata.second;
}
StrVec::~StrVec()
{
free();
}
StrVec & StrVec::operator=(const StrVec & rhs)
{
std::pair<std::string *, std::string *> data = alloc_n_copy(rhs.begin(), rhs.end());
free();
elements = data.first;
first_free = cap = data.second;
return *this;
}
StrVec & StrVec::operator=(std::initializer_list<std::string> li)
{
std::pair<std::string *, std::string *> data = alloc_n_copy(li.begin(), li.end());
free();
elements = data.first;
first_free = cap = data.second;
return *this;
}
StrVec::StrVec(std::initializer_list<std::string> li)
{
std::pair<std::string *, std::string *> newdata = alloc_n_copy(li.begin(), li.end());
elements = newdata.first;
first_free = cap = newdata.second;
}
StrVec::StrVec(StrVec &&s) noexcept : elements(s.elements), first_free(s.first_free), cap(s.cap)
{
s.elements = s.first_free = s.cap = nullptr;
}
StrVec & StrVec::operator=(StrVec &&rhs) noexcept
{
if(this != &rhs)
{
free();
elements = rhs.elements;
first_free = rhs.first_free;
cap = rhs.cap;
rhs.elements = rhs.first_free = rhs.cap = nullptr;
}
return *this;
}
void StrVec::reallocate()
{
size_t newcapacity = size() ? 2 * size() : 1;
reserve(newcapacity);
}
void StrVec::reserve(size_t n)
{
if(n <= capacity())
return;
std::string * newdata = alloc.allocate(n);
std::string * dest = newdata;
std::string * elem = elements;
for(size_t i = 0; i != size(); ++i)
alloc.construct(dest++, std::move(*elem++));
free();
elements = newdata;
first_free = dest;
cap = elements + n;
}
void StrVec::resize(size_t n, const std::string &t)
{
if(n == size())
return;
if(n < size())
{
while(size() != n)
alloc.destroy(--first_free);
return;
}
if(n > capacity())
reserve(n);
while(size() != n)
alloc.construct(first_free++, t);
}
bool operator==(const StrVec &lhs, const StrVec &rhs)
{
if(lhs.size() != rhs.size())
return false;
for(const std::string *p1 = lhs.begin(), *p2 = rhs.begin(); p1 != lhs.end(); ++p1, ++p2)
if(*p1 != *p2)
return false;
return true;
}
bool operator!=(const StrVec &lhs, const StrVec &rhs)
{
return !(lhs == rhs);
}
bool operator<(const StrVec &lhs, const StrVec &rhs)
{
const std::string *p1 = lhs.begin(), *p2 = rhs.begin();
for( ; p1 != lhs.end() && p2 != rhs.end(); ++p1, ++p2)
{
if(*p1 < *p2)
return true;
if(*p1 > *p2)
return false;
}
if(p1 != lhs.end() && p2 == rhs.end())
return false;
if(p1 == lhs.end() && p2 != rhs.end())
return true;
return false;
}
bool operator<=(const StrVec &lhs, const StrVec &rhs)
{
return !(lhs > rhs);
}
bool operator>(const StrVec &lhs, const StrVec &rhs)
{
const std::string *p1 = lhs.begin(), *p2 = rhs.begin();
for( ; p1 != lhs.end() && p2 != rhs.end(); ++p1, ++p2)
{
if(*p1 > *p2)
return true;
if(*p1 < *p2)
return false;
}
if(p1 != lhs.end() && p2 == rhs.end())
return true;
if(p1 == lhs.end() && p2 != rhs.end())
return false;
return false;
}
bool operator>=(const StrVec &lhs, const StrVec &rhs)
{
return !(lhs < rhs);
}
std::string & StrVec::operator[](std::size_t n)
{
return elements[n];
}
const std::string & StrVec::operator[](std::size_t n) const
{
return elements[n];
}
#ifndef STRVEC_H
#define STRVEC_H
#include<string>
#include<memory>
#include<utility>
#include<initializer_list>
class StrVec
{
friend bool operator==(const StrVec &lhs, const StrVec &rhs);
friend bool operator<(const StrVec &lhs, const StrVec &rhs);
friend bool operator>(const StrVec &lhs, const StrVec &rhs);
public:
StrVec() : elements(nullptr), first_free(nullptr), cap(nullptr) { }
StrVec(const StrVec &);
StrVec & operator=(const StrVec &);
~StrVec();
StrVec(std::initializer_list<std::string> li);
StrVec(StrVec &&s) noexcept;
StrVec & operator=(StrVec &&rhs) noexcept;
StrVec & operator=(std::initializer_list<std::string> li);
std::string & operator[](std::size_t n);
const std::string & operator[](std::size_t n) const;
void push_back(const std::string &);
void push_back(std::string &&);
template <typename ... Args> void emplace_back(Args && ... args);
size_t size() const { return first_free - elements; }
size_t capacity() const { return cap - elements; }
std::string *begin() const { return elements; }
std::string *end() const { return first_free; }
void reserve(size_t);
void resize(size_t n, const std::string &t = std::string());
private:
static std::allocator<std::string> alloc;
void chk_n_alloc()
{
if(size() == capacity())
reallocate();
}
std::pair<std::string *, std::string *> alloc_n_copy(const std::string *, const std::string *);
void free();
void reallocate();
std::string * elements;
std::string * first_free;
std::string * cap;
};
bool operator==(const StrVec &lhs, const StrVec &rhs);
bool operator!=(const StrVec &lhs, const StrVec &rhs);
bool operator<(const StrVec &lhs, const StrVec &rhs);
bool operator<=(const StrVec &lhs, const StrVec &rhs);
bool operator>(const StrVec &lhs, const StrVec &rhs);
bool operator>=(const StrVec &lhs, const StrVec &rhs);
template <typename ... Args>
void StrVec::emplace_back(Args && ... args)
{
chk_n_alloc();
alloc.construct(first_free++, std::forward<Args>(args)...);
}
#endif
#include<iostream>
#include<string>
#include<utility>
#include "StrVec.h"
int main()
{
StrVec v;
v.push_back("123");
v.push_back("456");
v.push_back("789");
v = v;
v = {"123", "456", "789"};
StrVec v1 = v;
for(std::string * p = v1.begin(); p != v1.end(); ++p)
std::cout << *p << " ";
std::cout << std::endl;
v1.reserve(10);
std::cout << v1.size() << " " << v1.capacity() << std::endl;
v1.resize(20, "q");
std::cout << v1.size() << " " << v1.capacity() << std::endl;
for(std::string * p = v1.begin(); p != v1.end(); ++p)
std::cout << *p << " | ";
v1.resize(5);
std::cout << v1.size() << " " << v1.capacity() << std::endl;
for(std::string * p = v1.begin(); p != v1.end(); ++p)
std::cout << *p << " | ";
std::cout << std::endl;
StrVec v2 = {"1","2","3"};
for(std::string * p = v2.begin(); p != v2.end(); ++p)
std::cout << *p << " | ";
std::cout << std::endl;
StrVec v5(std::move(v2));
for(std::string * p = v5.begin(); p != v5.end(); ++p)
std::cout << *p << " | ";
std::cout << std::endl;
v = std::move(v5);
for(std::string * p = v.begin(); p != v.end(); ++p)
std::cout << *p << " | ";
std::cout << std::endl;
for(std::string * p = v5.begin(); p != v5.end(); ++p)
std::cout << *p << " | ";
std::cout << std::endl;
std::cout << (v == v5) << " " << (v > v5) << " " << (v < v5) << " " << (v <= v5) << " " << (v >= v5) << " " << std::endl;
v[1] = "12";
std::cout << v[0] << " "<< v[1] << std::endl;
v.emplace_back(10,'c');
for(std::string * p = v.begin(); p != v.end(); ++p)
std::cout << *p << " | ";
std::cout << std::endl;
return 0;
}
#ifndef VEC_H
#define VEC_H
#include<string>
#include<memory>
#include<utility>
#include<algorithm>
#include<initializer_list>
template <typename T> class Vec;
template <typename T>
bool operator==(const Vec<T> &lhs, const Vec<T> &rhs);
template <typename T>
bool operator!=(const Vec<T> &lhs, const Vec<T> &rhs);
template <typename T>
bool operator<(const Vec<T> &lhs, const Vec<T> &rhs);
template <typename T>
bool operator<=(const Vec<T> &lhs, const Vec<T> &rhs);
template <typename T>
bool operator>(const Vec<T> &lhs, const Vec<T> &rhs);
template <typename T>
bool operator>=(const Vec<T> &lhs, const Vec<T> &rhs);
template <typename T>
class Vec
{
friend bool operator== <T>(const Vec<T> &lhs, const Vec<T> &rhs);
friend bool operator< <T>(const Vec<T> &lhs, const Vec<T> &rhs);
friend bool operator> <T>(const Vec<T> &lhs, const Vec<T> &rhs);
public:
Vec() : elements(nullptr), first_free(nullptr), cap(nullptr) { }
Vec(const Vec &);
Vec & operator=(const Vec &);
~Vec();
Vec(std::initializer_list<T> li);
Vec(Vec &&s) noexcept;
Vec & operator=(Vec &&rhs) noexcept;
Vec & operator=(std::initializer_list<T> li);
T & operator[](std::size_t n);
const T & operator[](std::size_t n) const;
void push_back(const T &);
void push_back(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; }
template <typename ... Args> void emplace_back(Args && ... args);
void reserve(size_t);
void resize(size_t n, const T &t = T());
private:
static 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>
std::allocator<T> Vec<T>::alloc;
template <typename T>
void Vec<T>::push_back(const T &s)
{
chk_n_alloc();
alloc.construct(first_free++, s);
}
template <typename T>
void Vec<T>::push_back(T &&s)
{
chk_n_alloc();
alloc.construct(first_free++, std::move(s));
}
template <typename T>
std::pair<T *, T *> Vec<T>::alloc_n_copy(const T *b, const T *e)
{
T * data = alloc.allocate(e - b);
return {data, std::uninitialized_copy(b, e, data)};
}
template <typename T>
void Vec<T>::free()
{
if(elements)
{
Vec * th = this;
std::for_each(elements, first_free, [](T &s){ alloc.destroy(&s); } );
alloc.deallocate(elements, cap - elements);
}
}
template <typename T>
Vec<T>::Vec(const Vec & s)
{
std::pair<T *, T *> 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>
Vec<T> & Vec<T>::operator=(const Vec & rhs)
{
std::pair<T *, T *> 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=(std::initializer_list<T> li)
{
std::pair<T *, T *> data = alloc_n_copy(li.begin(), li.end());
free();
elements = data.first;
first_free = cap = data.second;
return *this;
}
template <typename T>
Vec<T>::Vec(std::initializer_list<T> li)
{
std::pair<T *, T *> newdata = alloc_n_copy(li.begin(), li.end());
elements = newdata.first;
first_free = cap = newdata.second;
}
template <typename T>
Vec<T>::Vec(Vec &&s) noexcept : elements(s.elements), first_free(s.first_free), cap(s.cap)
{
s.elements = s.first_free = s.cap = nullptr;
}
template <typename T>
Vec<T> & Vec<T>::operator=(Vec<T> &&rhs) noexcept
{
if(this != &rhs)
{
free();
elements = rhs.elements;
first_free = rhs.first_free;
cap = rhs.cap;
rhs.elements = rhs.first_free = rhs.cap = nullptr;
}
return *this;
}
template <typename T>
void Vec<T>::reallocate()
{
size_t newcapacity = size() ? 2 * size() : 1;
reserve(newcapacity);
}