Merge pull request #648 from cubbimew/travis-fixes

fix Travis CI issues caused by recent direct commits
This commit is contained in:
Gabriel Dos Reis 2016-07-28 09:24:26 -07:00 committed by GitHub
commit 72a58497a9

View File

@ -594,7 +594,7 @@ This example is easily simplified
void read(int* p, int n); // read max n integers into *p void read(int* p, int n); // read max n integers into *p
int a[100]; int a[100];
read(a,1000); // bad read(a, 1000); // bad
better better
@ -2687,7 +2687,7 @@ With C++11 we can write this, putting the results directly in existing local var
With C++17 we should be able to use "structured bindinds" to declare and initialize the multiple variables: With C++17 we should be able to use "structured bindinds" to declare and initialize the multiple variables:
auto [iter,success] = myset.insert("Hello"); // C++17 structured binding auto [iter, success] = myset.insert("Hello"); // C++17 structured binding
if (success) do_something_with(iter); if (success) do_something_with(iter);
##### Exception ##### Exception
@ -2699,7 +2699,7 @@ For example:
istream& operator>>(istream& is, string& s); // much like std::operator>>() istream& operator>>(istream& is, string& s); // much like std::operator>>()
for (string s; cin>>s; ) { for (string s; cin >> s; ) {
// do something with line // do something with line
} }
@ -2712,11 +2712,11 @@ such as `string` and `vector`, that needs to do free store allocations.
To compare, if we passed out all values as return values, we would something like this: To compare, if we passed out all values as return values, we would something like this:
pair<istream&,string> get_string(istream& is); // not recommended pair<istream&, string> get_string(istream& is); // not recommended
{ {
string s; string s;
cin>>s; cin >> s;
return {is,s}; return {is, s};
} }
for (auto p = get_string(cin); p.first; ) { for (auto p = get_string(cin); p.first; ) {
@ -2768,13 +2768,14 @@ It complicates checking and tool support.
##### Example ##### Example
void use(int* p, int nchar* s, int* q) void use(int* p, int n, char* s, int* q)
{ {
p[n-1] = 666; // Bad: we don't know if p points to n elements; assume it does not or use span<int> p[n-1] = 666; // Bad: we don't know if p points to n elements;
// assume it does not or use span<int>
cout << s; // Bad: we don't know if that s points to a zero-terminated array of char; // assume it does not or use zstring cout << s; // Bad: we don't know if that s points to a zero-terminated array of char;
// assume it does not or use zstring
delete q; // Bad: we don't know if *q is allocated on the free store; assume it does not or use owner delete q; // Bad: we don't know if *q is allocated on the free store;
//assume it does not or use owner
} }
better better
@ -2782,9 +2783,7 @@ better
void use2(span<int> p, zstring s, owner<int*> q) void use2(span<int> p, zstring s, owner<int*> q)
{ {
p[p.size()-1] = 666; // OK, a range error can be caught p[p.size()-1] = 666; // OK, a range error can be caught
cout << s; // OK cout << s; // OK
delete q; // OK delete q; // OK
} }
@ -6150,13 +6149,13 @@ This Shape hierarchy can be rewritten using interface inheritance:
class Shape { // pure interface class Shape { // pure interface
public: public:
virtual Point center() const =0; virtual Point center() const = 0;
virtual Color color() const =0; virtual Color color() const = 0;
virtual void rotate(int) =0; virtual void rotate(int) = 0;
virtual void move(Point p) =0; virtual void move(Point p) = 0;
virtual void redraw() =0; virtual void redraw() = 0;
// ... // ...
}; };
@ -6190,13 +6189,13 @@ First we devise a hierarchy of interface classes:
class Shape { // pure interface class Shape { // pure interface
public: public:
virtual Point center() const =0; virtual Point center() const = 0;
virtual Color color() const =0; virtual Color color() const = 0;
virtual void rotate(int) =0; virtual void rotate(int) = 0;
virtual void move(Point p) =0; virtual void move(Point p) = 0;
virtual void redraw() =0; virtual void redraw() = 0;
// ... // ...
}; };
@ -7479,9 +7478,12 @@ The default is the easiest to read and write.
##### Example ##### Example
enum class Direction : char { n, s, e, w, ne, nw, se, sw }; // underlying type saves space enum class Direction : char { n, s, e, w,
ne, nw, se, sw }; // underlying type saves space
enum class Webcolor : int { red = 0xFF0000, green = 0x00FF00, blue = 0x0000FF }; // underlying type is redundant enum class Webcolor : int { red = 0xFF0000,
green = 0x00FF00,
blue = 0x0000FF }; // underlying type is redundant
##### Note ##### Note
@ -7512,9 +7514,10 @@ The default gives a consequtive set of values that is good for `switch`-statemen
##### Example ##### Example
enum class Col1 { red, yellow, blue }; enum class Col1 { red, yellow, blue };
enum class Col2 { red=1, red=2, blue=2 }; // typo enum class Col2 { red = 1, red = 2, blue = 2 }; // typo
enum class Month { jan=1, feb, mar, apr, mar, jun, jul, august, sep, oct, nov, dec }; // starting with 1 is conventional enum class Month { jan = 1, feb, mar, apr, mar, jun,
enum class Base_flag { dec=1, oct=dec<<1, hex=dec<<2 }; // set of bits jul, august, sep, oct, nov, dec }; // starting with 1 is conventional
enum class Base_flag { dec = 1, oct = dec << 1, hex = dec << 2 }; // set of bits
Specifying values are neccessary to match conventional values (e.g., `Month`) Specifying values are neccessary to match conventional values (e.g., `Month`)
and where consecutive values are undesirable (e.g., to get separate bits as in `Base_flag`). and where consecutive values are undesirable (e.g., to get separate bits as in `Base_flag`).
@ -9417,28 +9420,28 @@ Requires messy cast-and-macro-laden code to get working right.
void error(int severity ...) // ``severity'' followed by a zero-terminated list of char*s; write the C-style strings to cerr void error(int severity ...) // ``severity'' followed by a zero-terminated list of char*s; write the C-style strings to cerr
{ {
va_list ap; // a magic type for holding arguments va_list ap; // a magic type for holding arguments
va_start(ap,severity); // arg startup: "severity" is the first argument of error() va_start(ap, severity); // arg startup: "severity" is the first argument of error()
for (;;) { for (;;) {
char* p = va_arg(ap,char*); // treat the next var as a char*; no checking: a cast in disguise char* p = va_arg(ap, char*); // treat the next var as a char*; no checking: a cast in disguise
if (p == nullptr) break; if (p == nullptr) break;
cerr << p << ' '; cerr << p << ' ';
} }
va_end(ap); // arg cleanup (don't forget this) va_end(ap); // arg cleanup (don't forget this)
cerr << '\en'; cerr << '\n';
if (severity) exit(severity); if (severity) exit(severity);
} }
void use() void use()
{ {
error(7,"this","is","an","error", nullptr); error(7, "this", "is", "an", "error", nullptr);
error(7); // crash error(7); // crash
error(7,"this","is","an","error"); // crash error(7, "this", "is", "an", "error"); // crash
const char* is = "is"; const char* is = "is";
string an = "an"; string an = "an";
error(7,"this","is,an,"error"); // crash error(7, "this", "is", an, "error"); // crash
} }
**Alternative**: Overloading. Templates. Variadic templates. **Alternative**: Overloading. Templates. Variadic templates.
@ -13511,10 +13514,10 @@ To say "`T` is `Sortable`":
// requires Sortable<T> // of type T which is the name of a type // requires Sortable<T> // of type T which is the name of a type
void sort(T&); // that is Sortable" void sort(T&); // that is Sortable"
template<Sortable T> // Better (assuming language support for concepts): "The parameter is of type T template<Sortable T> // Better (assuming support for concepts): "The parameter is of type T
void sort(T&); // which is Sortable" void sort(T&); // which is Sortable"
void sort(Sortable&); // Best (assuming language support for concepts): "The parameter is Sortable" void sort(Sortable&); // Best (assuming support for concepts): "The parameter is Sortable"
The shorter versions better match the way we speak. Note that many templates don't need to use the `template` keyword. The shorter versions better match the way we speak. Note that many templates don't need to use the `template` keyword.
@ -13864,11 +13867,11 @@ The compiler will select the overload and emit an appropriate error.
Complementary constraints are unfortunately common in `enable_if` code: Complementary constraints are unfortunately common in `enable_if` code:
template<typename T> template<typename T>
enable_if<!C<T>,void> // bad enable_if<!C<T>, void> // bad
f(); f();
template<typename T> template<typename T>
enable_if<C<T>,void> enable_if<C<T>, void>
f(); f();
@ -14277,14 +14280,15 @@ Eases tool creation.
template<typename C> template<typename C>
void sort(C& c) void sort(C& c)
{ {
std::sort(begin(c),end(c)); // necessary and useful dependency std::sort(begin(c), end(c)); // necessary and useful dependency
} }
template<typename Iter> template<typename Iter>
Iter algo(Iter first, Iter last) { Iter algo(Iter first, Iter last) {
for (; first!=last; ++first) { for (; first != last; ++first) {
auto x = sqrt(*first); // potentially surprising dependency: which sqrt()? auto x = sqrt(*first); // potentially surprising dependency: which sqrt()?
helper(first,x); // potentially surprising dependency: heper is chosen based on first and x helper(first, x); // potentially surprising dependency:
// helper is chosen based on first and x
TT var = 7; // potentially surprising dependency: which TT? TT var = 7; // potentially surprising dependency: which TT?
} }
} }
@ -14451,7 +14455,7 @@ This is a simplified version of `std::copy` (ignoring the possibility of non-con
template<> struct copy_trait<int> { using tab = pod_tag; }; // int is "plain old data" template<> struct copy_trait<int> { using tab = pod_tag; }; // int is "plain old data"
template<class Iter> template<class Iter>
Out copy_helper(Iter first, Iter last, Iter out, pog_tag) Out copy_helper(Iter first, Iter last, Iter out, pod_tag)
{ {
// use memmove // use memmove
} }
@ -14465,13 +14469,13 @@ This is a simplified version of `std::copy` (ignoring the possibility of non-con
template<class Itert> template<class Itert>
Out copy(Iter first, Iter last, Iter out) Out copy(Iter first, Iter last, Iter out)
{ {
return copy_helper(first,last,out, typename copy_trait<Iter>::tag{}) return copy_helper(first, last, out, typename copy_trait<Iter>::tag{})
} }
void use(vector<int>& vi, vector<int>& vi2, vector<string>& vs, vector<string>& vs2) void use(vector<int>& vi, vector<int>& vi2, vector<string>& vs, vector<string>& vs2)
{ {
copy(vi.begin(),vi.end(), vi2.begin()); // uses memmove copy(vi.begin(), vi.end(), vi2.begin()); // uses memmove
copy(vs.begin(),vs.end(), vs2.begin()); // uses a loop calling copy constructors copy(vs.begin(), vs.end(), vs2.begin()); // uses a loop calling copy constructors
} }
This is a general and powerful technique for compile-time algorithm selection. This is a general and powerful technique for compile-time algorithm selection.
@ -14528,7 +14532,7 @@ When `concept`s become widely available such alternatives can be distinguished d
auto x = T(u); // construction or cast? auto x = T(u); // construction or cast?
} }
f(1,"asdf); // bad: cast from const char* to int f(1, "asdf"); // bad: cast from const char* to int
##### Enforcement ##### Enforcement
@ -14564,9 +14568,9 @@ There are three major ways to let calling code customize a template.
template<class T> template<class T>
void test3(T t) void test3(T t)
// Invoke a "trait" // Invoke a "trait"
{ {
test_traits<T>::f(t); // require customizing test_traits<> to get non-default functions/types test_traits<T>::f(t); // require customizing test_traits<>
// to get non-default functions/types
} }
A trait is usually a type alias to compute a type, A trait is usually a type alias to compute a type,
@ -14993,15 +14997,16 @@ Documentation, readability, opportunity for reuse.
bool same(const Rec& a, const Rec& b) bool same(const Rec& a, const Rec& b)
{ {
return a.id==b.id; return a.id == b.id;
} }
vector<Rec*> find_id(const string& name); // find all records for "name" vector<Rec*> find_id(const string& name); // find all records for "name"
auto x = find_if(vr.begin(),vr.end(), auto x = find_if(vr.begin(), vr.end(),
[&](Rec& r) { [&](Rec& r) {
if (r.name.size()!=n.size()) return false; // name to compare to is in n if (r.name.size() != n.size()) return false; // name to compare to is in n
for (int i=0; i<r.name.size(); ++i) if (tolower(r.name[i])!=tolower(n[i])) return false; for (int i=0; i < r.name.size(); ++i)
if (tolower(r.name[i]) != tolower(n[i])) return false;
return true; return true;
} }
); );