Utilities
Loading...
Searching...
No Matches
std_lib_facilities.h
Go to the documentation of this file.
1/*
2std_lib_facilities.h
3*/
4
5/*
6simple "Programming: Principles and Practice using C++ (second edition)" course header to
7be used for the first few weeks.
8It provides the most common standard headers (in the global namespace)
9and minimal exception/error support.
10
11Students: please don't try to understand the details of headers just yet.
12All will be explained. This header is primarily used so that you don't have
13to understand every concept all at once.
14
15By Chapter 10, you don't need this file and after Chapter 21, you'll understand it
16
17Revised April 25, 2010: simple_error() added
18
19Revised November 25 2013: remove support for pre-C++11 compilers, use C++11: <chrono>
20Revised November 28 2013: add a few container algorithms
21Revised June 8 2014: added #ifndef to workaround Microsoft C++11 weakness
22Revised Febrary 2 2015: randint() can now be seeded (see exercise 5.13).
23Revised August 3, 2020: a cleanup removing support for ancient compilers
24*/
25
26#ifndef H112
27#define H112 080315L
28
29
30#include<iostream>
31#include<iomanip>
32#include<fstream>
33#include<sstream>
34#include<cmath>
35#include<cstdlib>
36#include<string>
37#include<list>
38#include <forward_list>
39#include<vector>
40#include<unordered_map>
41#include<algorithm>
42#include <array>
43#include <regex>
44#include<random>
45#include<stdexcept>
46
47//------------------------------------------------------------------------------
48
49
50typedef long Unicode;
51
52//------------------------------------------------------------------------------
53
54using namespace std;
55
56template<class T> string to_string(const T& t)
57{
59 os << t;
60 return os.str();
61}
62
63struct Range_error : out_of_range { // enhanced vector range error reporting
64 int index;
65 Range_error(int i) :out_of_range("Range error: " + to_string(i)), index(i) { }
66};
67
68
69// trivially range-checked vector (no iterator checking):
70template< class T> struct Vector : public std::vector<T> {
71 using size_type = typename std::vector<T>::size_type;
72
73/* #ifdef _MSC_VER
74 // microsoft doesn't yet support C++11 inheriting constructors
75 Vector() { }
76 explicit Vector(size_type n) :std::vector<T>(n) {}
77 Vector(size_type n, const T& v) :std::vector<T>(n, v) {}
78 template <class I>
79 Vector(I first, I last) : std::vector<T>(first, last) {}
80 Vector(initializer_list<T> list) : std::vector<T>(list) {}
81*/
82 using std::vector<T>::vector; // inheriting constructor
83
84 T& operator[](unsigned int i) // rather than return at(i);
85 {
86 if (/*i<0 || */ this->size() <= i) throw Range_error(i);
87 return std::vector<T>::operator[](i);
88 }
89 const T& operator[](unsigned int i) const
90 {
91 if (/*i<0 || */ this->size() <= i) throw Range_error(i);
92 return std::vector<T>::operator[](i);
93 }
94};
95
96// disgusting macro hack to get a range checked vector:
97#define vector Vector
98
99// trivially range-checked string (no iterator checking):
100struct String : std::string {
101 using size_type = std::string::size_type;
102 // using string::string;
103
104 char& operator[](unsigned int i) // rather than return at(i);
105 {
106 if (/*i<0 || */ size() <= i) throw Range_error(i);
107 return std::string::operator[](i);
108 }
109
110 const char& operator[](unsigned int i) const
111 {
112 if (/*i<0 || */ size() <= i) throw Range_error(i);
113 return std::string::operator[](i);
114 }
115};
116
117
118namespace std {
119
120 template<> struct hash<String>
121 {
122 size_t operator()(const String& s) const
123 {
124 return hash<std::string>()(s);
125 }
126 };
127
128} // of namespace std
129
130
131struct Exit : runtime_error {
132 Exit() : runtime_error("Exit") {}
133};
134
135// error() simply disguises throws:
136inline void error(const string& s)
137{
138 throw runtime_error(s);
139}
140
141inline void error(const string& s, const string& s2)
142{
143 error(s + s2);
144}
145
146inline void error(const string& s, int i)
147{
149 os << s << ": " << i;
150 error(os.str());
151}
152
153
154template<class T> char* as_bytes(T& i) // needed for binary I/O
155{
156 void* addr = &i; // get the address of the first byte
157 // of memory used to store the object
158 return static_cast<char*>(addr); // treat that memory as bytes
159}
160
161
162inline void keep_window_open()
163{
164 cin.clear();
165 cout << "Please enter a character to exit\n";
166 char ch;
167 cin >> ch;
168 return;
169}
170
171inline void keep_window_open(string s)
172{
173 if (s == "") return;
174 cin.clear();
175 cin.ignore(120, '\n');
176 for (;;) {
177 cout << "Please enter " << s << " to exit\n";
178 string ss;
179 while (cin >> ss && ss != s)
180 cout << "Please enter " << s << " to exit\n";
181 return;
182 }
183}
184
185
186
187// error function to be used (only) until error() is introduced in Chapter 5:
188inline void simple_error(string s) // write ``error: s and exit program
189{
190 cerr << "error: " << s << '\n';
191 keep_window_open(); // for some Windows environments
192 exit(1);
193}
194
195// make std::min() and std::max() accessible on systems with antisocial macros:
196#undef min
197#undef max
198
199
200// run-time checked narrowing cast (type conversion). See ???.
201template<class R, class A> R narrow_cast(const A& a)
202{
203 R r = R(a);
204 if (A(r) != a) error(string("info loss"));
205 return r;
206}
207
208// random number generators. See 24.7.
209
211{
212 static default_random_engine ran; // note: not thread_local
213 return ran;
214};
215
216inline void seed_randint(int s) { get_rand().seed(s); }
217
218inline int randint(int min, int max) { return uniform_int_distribution<>{min, max}(get_rand()); }
219
220inline int randint(int max) { return randint(0, max); }
221
222//inline double sqrt(int x) { return sqrt(double(x)); } // to match C++0x
223
224// container algorithms. See 21.9. // C++ has better versions of this:
225
226template<typename C>
227using Value_type = typename C::value_type;
228
229template<typename C>
230using Iterator = typename C::iterator;
231
232template<typename C>
233// requires Container<C>()
234void sort(C& c)
235{
236 std::sort(c.begin(), c.end());
237}
238
239template<typename C, typename Pred>
240// requires Container<C>() && Binary_Predicate<Value_type<C>>()
241void sort(C& c, Pred p)
242{
243 std::sort(c.begin(), c.end(), p);
244}
245
246template<typename C, typename Val>
247// requires Container<C>() && Equality_comparable<C,Val>()
249{
250 return std::find(c.begin(), c.end(), v);
251}
252
253template<typename C, typename Pred>
254// requires Container<C>() && Predicate<Pred,Value_type<C>>()
256{
257 return std::find_if(c.begin(), c.end(), p);
258}
259
260#endif //H112
void seed_randint(int s)
typename C::value_type Value_type
default_random_engine & get_rand()
void sort(C &c)
void error(const string &s)
string to_string(const T &t)
Iterator< C > find_if(C &c, Pred p)
char * as_bytes(T &i)
void simple_error(string s)
void keep_window_open()
Iterator< C > find(C &c, Val v)
typename C::iterator Iterator
R narrow_cast(const A &a)
#define vector
int randint(int min, int max)
long Unicode
const char & operator[](unsigned int i) const
std::string::size_type size_type
char & operator[](unsigned int i)
typename std::vector< T >::size_type size_type
T & operator[](unsigned int i)
const T & operator[](unsigned int i) const
size_t operator()(const String &s) const