C-style arrays should be C++ std::array's

To explain the motivation for this change, I turn to
https://isocpp.org/wiki/faq/containers#arrays-are-evil, typos
and all:

BEGIN QUOTE
	Why should I use container classes rather than simple arrays?

	In terms of time and space, a contiguous array of any
	kind is just about the optimal construct for accessing a
	sequence of objects in memory, and if you are serious
	about performance in any language you will “often” use
	arrays.

	However, there are good arrays (e.g., containers with
	contiguous storage such as 'std::array' and
	'std::vector') and there are bad arrays (e.g., C []
	arrays). Simple C [] arrays are 'evil' because a C array
	is a very low level data structure with a vast potential
	for misuse and errors and in essentially all cases there
	are better alternatives – where “better” means easier to
	write, easier to read, less error prone, and as fast.

	The two fundamental problems with C arrays are that
		* a C array doesn’t know its own size
		* the name of a C array converts to a pointer to
		  its first element at the slightest provocation

	Consider some examples:
		void f(int a[], int s)
		{
		    // do something with a; the size of a is s
		    for (int i = 0; i<s; ++i) a[i] = i;
		}
		int arr1[20];
		int arr2[10];
		void g()
		{
		    f(arr1,20);
		    f(arr2,20);
		}
	The second call will scribble all over memory that
	doesn’t belong to 'arr2'. Naturally, a programmer
	usually gets the size right, but it’s extra work and
	every so often someone makes a mistake. You should
	prefer the simpler and cleaner version using the
	standard library 'vector' or 'array':
		void f(vector<int>& v)
		{
		    // do something with v
		    for (int i = 0; i<v.size(); ++i) v[i] = i;
		}
		vector<int> v1(20);
		vector<int> v2(10);
		void g()
		{
		    f(v1);
		    f(v2);
		}
		template<size_t N> void f(array<int, N>& v)
		{
		    // do something with v
		    for (int i = 0; i<N; ++i) v[i] = i;
		}
		array<int, 20> v1;
		array<int, 10> v2;
		void g()
		{
		    f(v1);
		    f(v2);
		}
	Since a C array doesn’t know its size, there can be no
	array assignment:
		void f(int a[], int b[], int size)
		{
		    a = b;            // not array assignment
		    memcpy(a,b,size); // a = b
		    // ...
		}
	Again, prefer 'vector' or 'array':
		// This one can result in a changing size
		void g(vector<int>& a, vector<int>& b)
		{
		    a = b;
		    // ...
		}
		// In this one, a and b must be the same size
		template<size_t N>
		void g(array<int, N>& a, array<int, N>& b)
		{
		    a = b;
		    // ...
		}
	Another advantage of 'vector' here is that 'memcpy()' is
	not going to do the right thing for elements with copy
	constructors, such as 'string's.
		void f(string a[], string b[], int size)
		{
		    a = b;            // not array assignment
		    memcpy(a,b,size); // disaster
		    // ...
		}
		void g(vector<string>& a, vector<string>& b)
		{
		    a = b;
		    // ...
		}
	A normal C array is of a fixed size determined at
	compile time (ignoring C99 VLAs, which currently have no
	analog in ISO C++):
		const int S = 10;
		void f(int s)
		{
		    int a1[s];    // error
		    int a2[S];    // ok
		    // if I want to extend a2, I'll have to change to an array
		    // allocated on free store using malloc() and use realloc()
		    // ...
		}
	To contrast:
		const int S = 10;
		void g(int s)
		{
		    vector<int> v1(s);    // ok
		    vector<int> v2(S);    // ok
		    v2.resize(v2.size()*2);
		    // ...
		}
	C99 allows variable array bounds for local arrays, but
	those VLAs have their own problems. The way that array
	names “decay” into pointers is fundamental to their use
	in C and C++. However, array decay interacts very badly
	with inheritance. Consider:
		class Base { void fct(); /* ... */ };
		class Derived : Base { /* ... */ };
		void f(Base* p, int sz)
		{
		    for (int i=0; i<sz; ++i) p[i].fct();
		}
		Base ab[20];
		Derived ad[20];
		void g()
		{
		    f(ab,20);
		    f(ad,20);    // disaster!
		}
	In the last call, the 'Derived[]' is treated as a
	'Base[]' and the subscripting no longer works correctly
	when 'sizeof(Derived)!=sizeof(Base)' – as will be the
	case in most cases of interest. If we used 'vectors'
	instead, the error would be caught at compile time:
		void f(vector<Base>& v)
		{
		    for (int i=0; i<v.size(); ++i) v[i].fct();
		}
		vector<Base> ab(20);
		vector<Derived> ad(20);
		void g()
		{
		    f(ab);
		    f(ad);    // error: cannot convert a vector<Derived> to a vector<Base>
		}
	We find that an astonishing number of novice programming
	errors in C and C++ relate to (mis)uses of C arrays. Use
	'std::vector' or 'std::array' instead.

	Let’s assume the best case scenario: you’re an
	experienced C programmer, which almost by definition
	means you’re pretty good at working with arrays. You
	know you can handle the complexity; you’ve done it for
	years. And you’re smart — the smartest on the team — the
	smartest in the whole company. But even given all that,
	please read this entire FAQ and think very carefully
	about it before you go into “business as usual” mode.

	Fundamentally it boils down to this simple fact: C++ is
	not C. That means (this might be painful for you!!)
	you’ll need to set aside some of your hard earned wisdom
	from your vast experience in C. The two languages simply
	are different. The “best” way to do something in C is
	not always the same as the “best” way to do it in C++.
	If you really want to program in C, please do yourself a
	favor and program in C. But if you want to be really
	good at C++, then learn the C++ ways of doing things.
	You may be a C guru, but if you’re just learning C++,
	you’re just learning C++ — you’re a newbie. (Ouch; I
	know that had to hurt. Sorry.)

	Here’s what you need to realize about containers vs.
	arrays:
		1. Container classes make programmers more
		   productive. So if you insist on using arrays
		   while those around are willing to use
		   container classes, you’ll probably be less
		   productive than they are (even if you’re
		   smarter and more experienced than they are!).
		2. Container classes let programmers write more
		   robust code. So if you insist on using arrays
		   while those around are willing to use
		   container classes, your code will probably
		   have more bugs than their code (even if
		   you’re smarter and more experienced).
		3. And if you’re so smart and so experienced
		   that you can use arrays as fast and as safe
		   as they can use container classes, someone
		   else will probably end up maintaining your
		   code and they’ll probably introduce bugs. Or
		   worse, you’ll be the only one who can
		   maintain your code so management will yank
		   you from development and move you into a
		   full-time maintenance role — just what you
		   always wanted!

	Here are some specific problems with arrays:
		1. Subscripts don’t get checked to see if they
		   are out of bounds. (Note that some container
		   classes, such as 'std::vector', have methods
		   to access elements with or without bounds
		   checking on subscripts.)
		2. Arrays often require you to allocate memory
		   from the heap (see below for examples), in
		   which case you must manually make sure the
		   allocation is eventually deleted (even when
		   someone throws an exception). When you use
		   container classes, this memory management is
		   handled automatically, but when you use
		   arrays, you have to manually write a bunch of
		   code (and unfortunately that code is often
		   subtle and tricky) to deal with this. For
		   example, in addition to writing the code that
		   destroys all the objects and deletes the
		   memory, arrays often also force you you to
		   write an extra try block with a 'catch'
		   clause that destroys all the objects, deletes
		   the memory, then re-throws the exception.
		   This is a real pain in the neck, as shown
		   here. When using container classes, things
		   are much easier.
		3. You can’t insert an element into the middle
		   of the array, or even add one at the end,
		   unless you allocate the array via the heap,
		   and even then you must allocate a new array
		   and copy the elements.
		4. Container classes give you the choice of
		   passing them by reference or by value, but
		   arrays do not give you that choice: they are
		   always passed by reference. If you want to
		   simulate pass-by-value with an array, you
		   have to manually write code that explicitly
		   copies the array’s elements (possibly
		   allocating from the heap), along with code to
		   clean up the copy when you’re done with it.
		   All this is handled automatically for you if
		   you use a container class.
		5. If your function has a non-static local array
		   (i.e., an “automatic” array), you cannot
		   return that array, whereas the same is not
		   true for objects of container classes.

	Here are some things to think about when using containers:
		1. Different C++ containers have different
		   strengths and weaknesses, but for any given
		   job there’s usually one of them that is
		   better — clearer, safer, easier/cheaper to
		   maintain, and often more efficient — than an
		   array. For instance,
			* You might consider a 'std::map'
			  instead of manually writing code for a
			  lookup table.
			* A 'std::map' might also be used for a
			  sparse array or sparse matrix.
			* A 'std::array' is the most array-like
			  of the standard container classes, but
			  it also offers various extra features
			  such as bounds checking via the 'at()'
			  member function, automatic memory
			  management even if someone throws an
			  exception, ability to be passed both
			  by reference and by value, etc.
			* A 'std::vector' is the second-most
			  array-like of the standard container
			  classes, and offers additional extra
			  features over 'std::array' such as
			  insertions/removals of elements.
			* A 'std::string' is almost always
			  better than an array of 'char' (you
			  can think of a 'std::string' as a
			  “container class” for the sake of this
			  discussion).
		2. Container classes aren’t best for
		   /everything/, and sometimes you may need to
		   use arrays. But that should be very rare, and
		   if/when it happens:
			* Please design your container class’s
			  public interface in such a way that
			  the code that uses the container class
			  is unaware of the fact that there is
			  an array inside.
			* The goal is to “bury” the array inside
			  a container class. In other words,
			  make sure there is a very small number
			  of lines of code that directly touch
			  the array (just your own methods of
			  your container class) so everyone else
			  (the users of your container class)
			  can write code that doesn’t depend on
			  there being an array inside your
			  container class.

	To net this out, arrays really are 'evil'. You may not
	think so if you’re new to C++. But after you write a big
	pile of code that uses arrays (especially if you make
	your code leak-proof and exception-safe), you’ll learn —
	the hard way. Or you’ll learn the easy way by believing
	those who’ve already done things like that. The choice
	is yours.
END QUOTE