    <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:content="http://purl.org/rss/1.0/modules/content/">
     <channel>
        <title>ACCU  :: Code Critique Competition 108</title>
        <link>https://members.accu.org/index.php/articles/2433</link>
        <description>Professionalism in Programming</description>
        <dc:language>en-us</dc:language> 
        <dc:creator>Administrator</dc:creator> 
        <admin:generatorAgent rdf:resource="http://www.xaraya.org" /> 
        <admin:errorReportsTo rdf:resource="mailto:webeditor@accu.org" />
       <sy:updatePeriod>hourly</sy:updatePeriod>
       <sy:updateFrequency>1</sy:updateFrequency>
       <docs>http://backend.userland.com/rss</docs>




<div class="xar-mod-head"><span class="xar-mod-title">Student Code Critiques from CVu journal. + CVu Journal Vol 29, #5 - November 2017</span></div>

<table border="0" cellpadding="1" cellspacing="0">
    <tbody>
    <tr>
        <td valign="top">
            Browse in :
       </td>
       <td valign="top">

                                            <a href="https://members.accu.org/index.php/articles/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c184/">Journal Columns</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c183/">Code Critique</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c76/">Journals</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c77/">CVu</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c379/">295</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/c183-379/">Any of these categories</a>

                    -                        <a href="https://members.accu.org/index.php/articles/c183+379/">All of these categories</a>
<br />
</td>
   </tr>
   </tbody>
</table>




<div class="xar-error">
   <p>
 <strong>Note:</strong> when you create a new publication type,
the articles module will automatically use the templates
<em>user-display-[publicationtype].xt</em>
and <em>user-summary-[publicationtype].xt</em>.
If those templates do not exist when you try to preview or display a new article,
you'll get this warning :-)  Please place your own templates in themes/<em>yourtheme</em>/modules/articles . The templates will get the extension .xt there. </p>
</div>
<div class="xar-norm xar-standard-box-padding">
   <h1><strong>Title:</strong>&nbsp;Code Critique Competition 108</h1>
<p><strong>Author:</strong>&nbsp;Bob Schmidt</p>
<p>
<strong>Date:</strong> 03 November 2017 16:48:07 +00:00 or Fri, 03 November 2017 16:48:07 +00:00</p>
<p><strong>Summary:</strong>&nbsp;Set and collated by Roger Orr. A book prize is awarded for the best entry.</p>
<p><strong>Body:</strong>&nbsp;<p class="EditorIntro">Please note that participation in this competition is open to all members, whether novice or expert. Readers are also encouraged to comment on published entries, and to supply their own possible code samples for the competition (in any common programming language) to scc@accu.org.</p>

<p class="EditorIntro">Note: If you would rather not have your critique visible online, please inform me. (Email addresses are not publicly visible.)</p>

<h2>Last issueâ€™s code</h2>

<p class="blockquote">I want to collect the meals needed for attendees for a one-day event so Iâ€™m reading lines of text with the name and a list of the meals needed, and then writing the totals. However, the totals are wrong â€“ but I canâ€™t see why:</p>

<pre class="programlisting">
    &gt; meals
    Roger breakfast lunch
    John lunch dinner
    Peter dinner
    
    Total: 3 breakfast: 3 lunch: 2 dinner: 2</pre>

<p class="blockquote">There should only be 1 breakfast, not 3!</p>

<p>Please can you help the programmer find the bug â€“ and suggest some possible improvements to the program!</p>

<ul>
	<li>Listing 1 contains <span class="filename">meal.h</span></li>
	<li>Listing 2 (overleaf) contains <span class="filename">meals.cpp</span></li>
</ul>

<table class="sidebartable">
	<tr>
		<td>
			<pre class="programlisting">
#pragma once
#include &lt;iosfwd&gt;
#include &lt;sstream&gt;
#include &lt;string&gt;
enum class meal : int
{
   breakfast, lunch, dinner,
};

// Used for name &lt;=&gt; value conversion
struct
{
  meal value;
  std::string name;
} names[] =
{
  { meal::breakfast, &quot;breakfast&quot; },
  { meal::lunch, &quot;lunch&quot; },
  { meal::dinner, &quot;dinner&quot; },
};

std::istream &amp;operator&gt;&gt;(std::istream &amp;is, 
  meal &amp;m)
{
  std::string name;
  if (is &gt;&gt; name)
  {
    for (auto p : names)
    {
      if (p.name == name)
        m = p.value;
    }
  }  return is;
}

std::ostream &amp;operator&lt;&lt;(std::ostream &amp;os, 
  meal const m)
{
  for (auto p : names)
  {
    if (p.value == m)
      os &lt;&lt; p.name;
  }
  return os;
}

// Type-safe operations
constexpr meal operator+(meal a, meal b)
{
  return meal(int(a) + int(b));
}

meal operator+=(meal &amp;a, meal b)
{
  a = a + b;
  return a;
}

constexpr meal operator|(meal a, meal b)
{
  return meal(int(a) | int(b));
}

constexpr meal operator&amp;(meal a, meal b)
{
  return meal(int(a) &amp; int(b));
}

// Check distinctness
static_assert((meal::breakfast | meal::lunch |
 meal::dinner) == (meal::breakfast +
 meal::lunch + meal::dinner), &quot;not distinct&quot;);
			</pre>
		</td>
	</tr>
	<tr>
		<td class="title">Listing 1</td>
	</tr>
</table>

<table class="sidebartable">
	<tr>
		<td>
			<pre class="programlisting">
#include &quot;meal.h&quot;
#include &lt;iostream&gt;
#include &lt;list&gt;
struct attendee
{
   std::string name;
   meal meals; // set of meals
};

using attendees = std::list&lt;attendee&gt;;

attendees get_attendees(std::istream &amp;is)
{
  attendees result;
  std::string line;
  while (std::getline(is, line))
  {
    std::istringstream iss(line);
    std::string name;
    iss &gt;&gt; name;
    meal meal, meals{};
    while (iss &gt;&gt; meal)
      meals += meal; // add in each meal
    if (is.fail())
      throw std::runtime_error(&quot;Input error&quot;);
    result.push_back({name, meals});
  }
  return result;
}
			</pre>
		</td>
	</tr>
	<tr>
		<td class="title">Listing 2</td>
	</tr>
</table>

<h2>Critiques</h2>

<h3>Kaartic Sivaraam</h3>

<p>The issue seems to be with the â€˜enum classâ€™</p>

<pre class="programlisting">
  enum class meal : int
  {
    breakfast, lunch, dinner,
  };</pre>

<p>They have the values of 0, 1, 2 each having â€˜at mostâ€™ one bit set in binary, of course. The issue is that as â€˜breakfastâ€™ has value of 0 it is impossible to distinguish between the one who wants breakfast and who doesnâ€™t. Thatâ€™s because the expression</p>

<pre class="programlisting">
  (item.meals &amp; m) == m</pre>
  
<p>always evaluates to <code>true</code> for the value of <code>breakfast</code> (0). The following change would fix the issue.</p>

<pre class="programlisting">
  enum class meal : int
  {
    breakfast=1, lunch=2, dinner=4,
  };</pre>
  
<p>Further, the following method seems to need a little tweak,</p>

<pre class="programlisting">
  std::istream &amp;operator&gt;&gt;(std::istream &amp;is,
    meal &amp;m)</pre>
	
<p>It doesnâ€™t seem to be setting the <code>failbit</code> of the <code>is</code> in case it doesnâ€™t identify the â€˜validâ€™ input. I guess the following change fixes that. Correct me, if Iâ€™m wrong.</p>

<pre class="programlisting">
  std::istream &amp;operator&gt;&gt;(std::istream &amp;is,
    meal &amp;m)
  {
    std::string name;
    bool found = false;
    if (is &gt;&gt; name)
    {
      for (auto p : names)
      {
        if (p.name == name) {
          m = p.value;
          found = true;
          break;
        }
      }
    }
    if(!found)
      is.setstate(std::ios::failbit);
    return is;
  }</pre>
  
<p>Nitpicking a little more, the file <span class="filename">meal.h</span> doesnâ€™t look like a header though it has the <span class="filename">.h</span> suffix, which isnâ€™t such a good thing. It should be split into two files named <span class="filename">meal.h</span> and <span class="filename">meal.cpp</span>. The file currently named <span class="filename">meals.cpp</span> should be renamed to something else more meaningful, probably <span class="filename">attendee_meal_requirements.cpp</span>.</p>

<h3>Russel Winder</h3>

<p>Having looked at the C++ code presented for Code Critique 107, my reaction was WTF. After a moment to collect myself, I realised: C++ is just totally the wrong language with which to attempt the problem as stated. Thus I provide no answer to â€œ<em>Please can you help the programmer find his bug</em>â€ (*), and thus likely relinquish any possibility of winning this code critique. However for â€œ<em>suggest some other possible problems with their program.</em>â€ I suggest: the single biggest problem with this code is that it is written in C++.</p>

<p>Clearly I need to follow up on this conclusion with some positive and constructive thoughts.</p>

<p>What language would be good for this problem? The answer is clearly (**) Python (<a href="https://www.python.org">https://www.python.org</a>). In <span class="filename">rw_meals.py</span> I provide a program that answers the problem as set by â€œIâ€. Python has proper enums and sets, so obviates the need for all the extra code to be found in the C++ files: â€œIâ€ had some good implementation ideas, but trying to realise them in C++ is, well let us be kind and say non-trivial. Multiple calls of the C++ count function are replaced by a single call of the Python reduce function from the functools package (Python 3 is, of course, assumed here). The brevity and clarity of the Python code mean that it is likely right just by observation. However, given the test data:</p>

<pre class="programlisting">
 |&gt; rw_meals.py
    Roger breakfast lunch
    John lunch dinner
    Peter dinner
    Total: 3, breakfast: 1, lunch: 2, dinner: 2</pre>
	
<p>we discover the code actually does give the answer expected. Obviously though this is but a single functional test, more tests, unit as well as functional should be provided if the code is to go into service for more than this one occasion.</p>

<p>Of course there will be people unwilling to accept this Python code as a solution because it isnâ€™t native code, or some other third rate excuse of this sort. OK, I shall cope with this quasi-objection by providing a solution using D (<a href="https://dlang.org">https://dlang.org</a>). In <span class="filename">rw_meals.d</span> is code that is very similar to the Python code, and produces the same result, the correct result:</p>

<pre class="programlisting">
 |&gt; rdmd rw_meals.d
    Roger breakfast lunch
    John lunch dinner
    Peter dinner
    Total: 3, breakfast: 1, lunch: 2, dinner: 2</pre>

<p>D doesnâ€™t have a built in set type, nor does it have an explicit set type in the standard library. The obvious (***) choices for implementing a set in D are to use a Red-Black Tree (there is an implementation in the standard library) or use an associative array (aka hash map, dictionary). In this case, I have used an associative array with the value of each key being the same as the key, which is about as close to a hash set as makes little difference.</p>

<p>I wonder what a good C++ code would look like? I am not sure I actually care as I have Python and D versions that satisfy me. Use the right tool for the right job as the saying goes.</p>

<h4>Notes</h4>

<p>(*) Let us assume â€œIâ€ is actually a man, rather than this being bad phrasing by the CVu team.</p>
<p>(**) Though obviously others will say Ruby, or Lisp, orâ€¦ well anything other than C++ really.</p>
<p>(***) To me, others may have a different view. </p>

<h4>Source code follows </h4>

<p class="EditorIntro">(Ed: reformatted slightly for publication.)</p>

<pre class="programlisting">
---- rw_meals.py ----
#!/usr/bin/env python3

import enum
import functools
import sys

class Meal(enum.Enum):
  breakfast = 'breakfast'
  lunch = 'lunch'
  dinner = 'dinner'

def get_attenders():
  result = {}
  for line in sys.stdin.readlines():
    data = line.strip().split()
    result[data[0]] =\
      {Meal(x) for x in data[1:]}
  return result

if __name__ == '__main__':
  attenders = get_attenders()
  counts = functools.reduce(
    lambda t, x: [t[0] +\
     (1 if Meal.breakfast in x else 0),
       t[1] + (1 if Meal.lunch in x else 0),
       t[2] + (1 if Meal.dinner in x else 0)],
        attenders.values(),
        [0, 0, 0]
  )
  print('Total: {}, breakfast: {}, lunch: {},\
   dinner: {}'.format(len(attenders),\
     *counts))

---- rw_meals.d ----
import std.algorithm: map, reduce;
import std.array: array, split;
import std.conv: to;
import std.stdio: lines, stdin, writefln,
  writeln;
import std.string: strip;

enum Meal: string {
  breakfast = &quot;breakfast&quot;,
  lunch = &quot;lunch&quot;,
  dinner = &quot;dinner&quot;,
}
auto getAttenders() {
  Meal[Meal][string] people;
  foreach (string line; stdin.lines()) {
    auto data = line.strip().split();
    Meal[Meal] mealSet;
    foreach (item;
      data[1..$].map!(a =&gt; to!Meal(a))) {
      mealSet[item] = item;
    }
    people[data[0]] = mealSet;
  }
  return people;
}
void main() {
  auto attenders = getAttenders();
  auto counts = reduce!(
    (t, x) =&gt; [t[0] + ((Meal.breakfast in x) ?
                        1 : 0),
               t[1] + ((Meal.lunch in x) ?
                        1 : 0),
               t[2] + ((Meal.dinner in x) ?
                        1 : 0)])(
                  [0, 0, 0],
                  attenders.byValue().array);
  writefln(&quot;Total: %d, breakfast: %d,&quot;
    &quot; lunch: %d, dinner: %d&quot;,
    attenders.length, counts[0], counts[1],
    counts[2]);
}</pre>

<h3>Jim Segrave</h3>

<p>The basic problem with this program is that the enums being used have the values breakfast: 0, lunch: 1 and dinner: 2. For every attendee, the test to see if they want breakfast tests:</p>

<pre class="programlisting">
  if((item.meals &amp; 0) == 0)</pre>
  
<p>which will always be true, so everyone is listed as wanting breakfast. This could be fixed by changing the enum definition to read:</p>

<pre class="programlisting">
  breakfast = 1, lunch = 2, dinner = 4,</pre>
  
<p>That still leaves problems: if someone orders breakfast twice on one line, theyâ€™ll get lunch instead, two lunches results in only dinner, etc. No error report is generated.</p>

<p>If someone orders two dinners, they only get the default breakfast, as the sum of two <code>dinner</code> enums is 4 and only 0, 1 and 2 are recognised in this code.</p>

<p>If one of the input lines is duplicated, that attendee will be scheduled to have two of each meal theyâ€™ve selected.</p>

<p>Invalid meal names are ignored, but not reported, which is probably not a good idea.</p>

<p>If someone is attending but doesnâ€™t choose any meal at all, with the current code she still gets put down for breakfast, which is wrong, if the enum is fixed, sheâ€™s not considered as attending and the number of attendees will only be the number of people having a meal, which should be separate counts.</p>

<p>Then there are style problems:</p>

<p><code>meal</code> is a class, but itâ€™s also the name of a variable, <code>attendees</code> is a class and again, the name of a variable, resulting in lines such as:</p>

<pre class="programlisting">
  meal meal, meals{};</pre>
  
<p>and</p>

<pre class="programlisting">
  auto attendees{ get_attendees( std::cin) };</pre>
  
<p>These are syntactically valid, but make reading the code difficult.</p>

<p>While itâ€™s valid to replace the body of <code>main</code> with a<code> try{} catch{}</code> block, it is, to say the least, not idiomatic.</p>

<p>The code uses function-style casts, the widespread consensus among C++ developers is that these and C-style casts should be replaced with the C++ cast operator.</p>

<p>The fact that no less than 4 operator overloads are used to perform dubious operations on enums (assigning the sum of two enums to an enum may be correct, but more often is not. The fact that these overloads are needed for handling enums should be a hint that an enum probably isnâ€™t the right type to use.)</p>

<p>Realistically, C++ isnâ€™t the right language for a task like this, an ordinary scripting language would be more appropriate (shorter, quicker to write, easier to debug). There are still other lurking issues â€“ the attendee names and meal names are case-sensitive. While it would be easy to ensure that the meal choices are handled caselessly, names are a different problem; they may contain UTF characters or they may not be convertible between lower and upper case (I believe that there is a variant of 'Iâ€™ in Turkish which has no lower case). The program also doesnâ€™t address names well in that it isnâ€™t designed to handle multi-word names (Gerrit Jan for example is often taken as a first name, not a first and middle name). The sample input uses first names only, for any sizeable list, the probability of a clash is not insignificant.</p>

<p>These problems require a lot more design and specification before trying to implement a real solution.</p>

<p>Nonetheless, Iâ€™ve re-written this in C++11 or later and addressed the earlier problems Iâ€™ve noted with duplicated entries on the same line, misspelled meal names, attendees choices being spread over more than one line. As a side benefit, itâ€™s possible to get a list of all the attendees, whether they are on a strict diet or not and, for each meal type, a list of who has chosen that meal. The program can either receive the list of attendees and their meal choices on stdin or read it from a file given as the sole argument to the program.</p>

<p>The meal choices have been moved to an initializer list at the top of the C++ file, simply adding another meal name to that list is sufficient to enable it to be processed (note the commented out <code>&quot;high-tea&quot;</code> in the initializer list).</p>

<p>Iâ€™ve attached the header file <span class="filename">meal.h</span>, the C++ code <span class="filename">cc106.cpp</span>, and a somewhat larger sample input file <span class="filename">cc106.input</span>.</p>

<pre class="programlisting">
-- revised header file --
#pragma once
#include &lt;fstream&gt;
#include &lt;initializer_list&gt;
#include &lt;iostream&gt;
#include &lt;iomanip&gt;
#include &lt;sstream&gt;
#include &lt;map&gt;
#include &lt;string&gt;
#include &lt;vector&gt;
class Meal_name {
 private:
    static int        new_id;
    static int        total_meals;
    int               count;
 public: 
    int         const id;
    std::string const meal_name;
    Meal_name(const char * name);
    // return number of these meals needed
    int  get_count() const { return count; }
    // return total number of meals
    // (all types)
    int  get_total_meals() const {
      return total_meals; }
    // somebody wants one of these meals
    void incr() { ++count; ++total_meals;}
};
using Selection    =
  std::pair&lt;const std::string, int&gt;;
using Attendee_map =
  std::map&lt;const std::string, int&gt;;
using Choice_vec   =
  std::vector&lt;Meal_name&gt;;

ssize_t lookup_meal(const std::string &amp; name,
  const Choice_vec &amp; vec);

Selection parse_line(
  const std::string &amp; input_line, int line_no,
  Attendee_map &amp; attendees,
  const Choice_vec &amp; vec);

void process_line(
  const std::string &amp; input_line, int line_no,
  Attendee_map &amp; attendees,
  Choice_vec &amp; vec);

-- revised C++ code --
#include &quot;meal.h&quot;
// initializer list with the names of all the
// different meals attendees can choose
std::initializer_list&lt;Meal_name&gt; all_choices 
{&quot;breakfast&quot;, &quot;lunch&quot;, &quot;dinner&quot;,
 /* &quot;high-tea&quot;, */ };
// ensure each Meal_name has an id which is a
// power of 2 (1, 2, 4, ...)
int Meal_name::new_id = 1;
Meal_name::Meal_name(const char * name)
: count(0),
  id(Meal_name::new_id), meal_name(name) {
  new_id *= 2;
}
int Meal_name::total_meals = 0;

// return index of meal 'name' in the vector
// or -1 if not found
ssize_t lookup_meal(const std::string &amp; name,
  const Choice_vec &amp; vec) {
  for(size_t i = 0; i &lt;  vec.size(); ++i) {
    if(vec[i].meal_name.compare(name) == 0) {
      return static_cast&lt;ssize_t&gt; (i);
    }
  }
  return -1;
}
// parse an input line, returning the attendee
// name (if any) and the bitwise
// or of the meals selected (blank lines will
// return this as zero)
Selection parse_line(
  const std::string &amp; input_line, int line_no,
  Attendee_map &amp; attendees,
  const Choice_vec &amp; vec) {

  std::string    name;
  std::istringstream is(input_line);
  // skip blank lines
  is &gt;&gt; name;
  if(name.size() == 0) {
    // skip blank lines
    return Selection{&quot;&quot;, 0};
  }
  // ensure the name is registered if new
  attendees.emplace(name, 0);
  int choice = 0;
  std::string meal;
  // accumulate all errors for this input line
  std::ostringstream errs;
  while(is &gt;&gt; meal) {
    auto idx = lookup_meal(meal, vec);
    if(idx &lt; 0) {
      errs &lt;&lt; &quot;\t\&quot;&quot; &lt;&lt; meal &lt;&lt;
        &quot;\&quot; is not a valid name for a meal&quot; &lt;&lt;
        std::endl;
      continue;
    }
    if((choice &amp; vec[idx].id) != 0) {
      errs &lt;&lt; &quot;\t\&quot;&quot; &lt;&lt; meal &lt;&lt;
        &quot;\&quot; appears more than once&quot;
        &quot; on this line&quot; &lt;&lt; std::endl;
      continue;
    }
    choice |= vec[idx].id;
  }
  // report if there were any problems on this
  // line
  if(errs.str().size() != 0) {
    std::cout &lt;&lt; &quot;Line &quot; &lt;&lt; line_no &lt;&lt; &quot;: &quot;
      &lt;&lt; input_line &lt;&lt; std::endl;
    std::cout &lt;&lt; errs.str();
  }
  return Selection(name, choice);
}
void process_line(
  const std::string &amp; input_line, int line_no, 
  Attendee_map &amp; attendees, Choice_vec &amp; vec) {
  Selection sel(parse_line(
    input_line, line_no, attendees, vec));
  const std::string &amp; name = sel.first;
  int choice = sel.second;
  if(choice == 0) {
    // blank line or no meals ordered on this
    // line
    return;
  }
  // previously ordered meals
  int old_choice = attendees[name];
  // newly ordered meals
  int new_choice = ~old_choice &amp; choice;
  int idx = 0;
  while(new_choice != 0) {
    if(new_choice &amp; 1) {
      // update no. of these meals ordered,
      // total meals
      vec[idx].incr();
    }
    new_choice &gt;&gt;= 1;
    ++idx;
  }
  attendees[name] = choice | old_choice;
}
int main(int argc, char **argv) {
  // set up the possible meals
  Choice_vec meal_choices(all_choices);
  // a map to track attendees
  Attendee_map attendees;
  // use cin unless there's a CLI parameter
  // (file of input lines)
  std::istream *f = &amp;std::cin;
  std::ifstream ifs;
  ifs.exceptions(std::ifstream::badbit |
    std::ifstream::failbit);
  try {
    if(argc &gt; 1) {
      ifs.open(argv[1]);
      f = &amp;ifs;
    }
    std::string line;
    int     line_no = 0;
    while(std::getline(*f, line)) {
      process_line(line, ++line_no,
        attendees, meal_choices);
      if(ifs.eof()) {
        ifs.close();
        break;
      }
    }
  }
  catch (std::ios_base::failure &amp;ex) {
    std::cerr &lt;&lt; &quot;File read error on &quot; &lt;&lt;
     ((argc &gt; 1) ? argv[1] : &quot;standard input&quot;)
     &lt;&lt; std::endl;
    exit(1);
  }
  std::cout &lt;&lt; &quot;\nAttendees: &quot; &lt;&lt;
    attendees.size() &lt;&lt; &quot; Total meals: &quot;;
  std::cout &lt;&lt;
    meal_choices[0].get_total_meals();
  for(auto meal : meal_choices) {
    std::cout &lt;&lt; &quot; &quot; &lt;&lt; meal.meal_name &lt;&lt; &quot;: &quot;
      &lt;&lt; meal.get_count();
  }
  std::cout &lt;&lt; &quot;\n\n&quot; &lt;&lt; std::setw(9) &lt;&lt;
    &quot;Attendees&quot; &lt;&lt; &quot;:&quot;;
  std::string separator = &quot; &quot;;
  for(auto participant: attendees) {
    std::cout &lt;&lt; separator &lt;&lt; 
      participant.first;
    separator = &quot;,  &quot;;
  }
  for(auto meal: meal_choices) {
    std::cout &lt;&lt; &quot;\n\n&quot; &lt;&lt; std::setw(9) &lt;&lt;
      meal.meal_name &lt;&lt; &quot;:&quot;;
    int  id = meal.id;
    separator = &quot; &quot;;
    for(auto participant: attendees) {
      if(participant.second &amp; id) {
        std::cout &lt;&lt; separator &lt;&lt;
          participant.first;
        separator = &quot;,  &quot;;
      }
    }
  }
  std::cout &lt;&lt; std::endl;
                       
}
-- sample input --
  Roger breakfast lunch dinner
  John  lunch dinner
  Peter dinner
  Dave

  Paul  dinner lunch
  Mary  dinner
  Sadie high-tea dinner
  Peter dinner lunch
  Dave

  Kevin breakfast lunch lunch
  Huey  lunch
  Alvin </pre>
  
<h3>Felix Petriconi &lt;felix@petriconi.net&gt;</h3>

<p>The main problem of the code is in the definition of the enum at the very beginning:</p>

<pre class="programlisting">
  enum class meal : int
  {
    breakfast,
    lunch,
    dinner
  };</pre>
  
<p>Later in the code the enum is used as a bit field, so the values were combined with plus and or operators. But the enum values were not defined as a bitfield. Per default the first enum is initialised with zero and the next ones follow continuously. So the present code is equal to </p>

<pre class="programlisting">
  enum class meal : int
  {
    breakfast = 0,
    lunch = 1,
    dinner = 2
  };</pre>
  
<p>So a combination of <code>breakfast | lunch</code> is equal to <code>0 | 1</code> which is equal to <code>1</code>. That means that the information of <code>breakfast</code> would be lost.</p>

<p>The bitfield should be corrected to </p>

<pre class="programlisting">
  enum class meal : int
  {
    breakfast = 1,
    lunch = 2,
    dinner = 4
  };</pre>
  
<p>Further this should be improved:</p>

<p>The choice of enum <code>class</code> at the beginning is good. This C++11 feature ensures that potential accidental conversions to an integer type will not happen. </p>

<p>The loop inside the following stream operator <code>std::istream &amp;operator&gt;&gt;(std::istream &amp;is, meal &amp;m)</code> should be changed to </p>

<pre class="programlisting">
  for (const auto&amp; p : names) {
    if (p.name == name)
      m = p.value;
  }</pre>

<p>because the existing code would create a copy of <code>p</code> for every loop iteration, which is a waste of resources. The same is valid for the loop inside the <code>std::ostream &amp;operator&lt;&lt;(std::ostream &amp;os, meal const m)</code> operator.</p>

<p>The operator </p>

<pre class="programlisting">
  constexpr meal operator+(meal a, meal b) {
    return meal(int(a) + int(b));
  }</pre>

<p>tries to combine enumerated values but it may return values that are no valid meal. So a dinner + lunch results into a 2+4 (or 1+2 in the original code) None of the results is a valid meal value. So the operator should not return a type of meal, but an <code>int</code>.</p>

<p>The same is true for the <code>meal operator+=(meal &amp;a, meal b)</code>.</p>

<p>So all operators would become:</p>

<pre class="programlisting">
  constexpr int operator+(meal a, meal b) {
    return int(a) + int(b);
  }
  int operator+=(int &amp;a, meal b) {
    a = a + int(b);
    return a;
  }
  constexpr int operator|(meal a, meal b) {
    return int(a) | int(b);
  }
  constexpr int operator&amp;(int a, meal b) {
    return a &amp; int(b);
  }</pre>

<p>The following <code>static_assert</code> is a great way to ensure that the bitfield uses each enum value exclusively. Since I changed the results type of the operators, the <code>static_assert</code> would have to be changed to </p>

<pre class="programlisting">
  static_assert((int(meal::breakfast) |
    int(meal::lunch) | int(meal::dinner)) ==
                (int(meal::breakfast) +
    int(meal::lunch) + int(meal::dinner)),
    &quot;not distinct&quot;);<p>The problem of possible invalid enum values implies that the struct</p>

  struct attendee
  {
    std::string name;
    meal meals; // set of meals

  };</pre>
  
<p>should be changed to</p>

<pre class="programlisting">
  struct attendee
  {
    std::string name;
    int meals; // set of meals
  };</pre>

<p>The type definition <code>using attendees = std::list&lt;attendee&gt;;</code> should be changed to <code>using attendees = std::vector&lt;attendee&gt;;</code> because all non array like types have a very bad cache locality. Sometime ago I read the good advice, that every usage of a different container than array or vector should be explicitly justified.</p>

<p>I had to change the <code>get_attendees</code> function on my Mac to</p>

<pre class="programlisting">
  attendees get_attendees(std::istream &amp;is) {
    attendees result;
    std::string line;
    while (std::getline(is, line)) {
      std::istringstream iss(line);
      if (line.empty())           // new line
        return result;            // new line

      std::string name;
      iss &gt;&gt; name;
      meal meal;
      int meals{};
      while (iss &gt;&gt; meal)
        meals += meal; // add in each meal
      if (is.fail())
        throw std::runtime_error(&quot;Input error&quot;);
      result.push_back({name, meals});
    }
    return result;
  }</pre>

<p>Otherwise the <code>while</code> loop did not terminate.</p>

<p>Inside the <code>while</code> loop the variable <code>meals</code> is default initialised by using <code>{}</code> to zero which is in the old code <code>breakfast</code>, even if the attendee might not have breakfast. So I would extend the enum class with a <code>none = 0</code> enumerated value so that a <code>{}</code> results in an initialised variable with no value.</p>

<p>The function <code>count</code></p>

<pre class="programlisting">
  size_t count(attendees a, meal m) {
    size_t result{};
    for (auto &amp;item : a) {
      // Check 'm' present in meals
      if ((item.meals &amp; m) == m)
        ++result;
    }
    return result;
  }</pre>
  
<p>is written with the correct intention in mind. But it fails when the first enumerated value has the implicit value of zero. The expression of <code>(time.meals &amp; 0) == 0</code> is always true. This results in the described failure of three breakfasts. Within this for loop I would change the type of the loop variable from <code>auto&amp;</code> to <code>const auto&amp;</code>, because the function has const semantics. As well there is no need to pass the <code>attendees a</code> parameter by value. In this case <code>const &amp;</code> would be better, so the unnecessary copy of the complete container could be avoided. So the improved version would look like:</p>

<pre class="programlisting">
  size_t count(const attendees&amp; a, meal m) {
    size_t result{};
    for (const auto&amp; item : a) {
      // Check 'm' present in meals
      if (static_cast&lt;meal&gt;(item.meals &amp; m)
          == m)
        ++result;
    }
    return result;
  }</pre>
  
<p>In a next step I would change the routine by using an STL algorithm, because here a reduce is implemented by hand.</p>

<pre class="programlisting">
  size_t count(const attendees&amp; a, meal m) {
    return std::accumulate(a.cbegin(), a.cend(),
      0,
      [m](std::size_t r, const auto&amp; item) {
         return r + (((item.meals &amp; m) != 0)
           ? 1 : 0);
    });
  }</pre>
  
<p>The <code>main</code> function is a little bit unusual, because its body is the <code>try</code>â€“<code>catch</code> block. So I would slightly change it to:</p>

<pre class="programlisting">
  int main() {
    try {
      auto attendees{get_attendees(std::cin)};
      std::cout &lt;&lt; &quot;Total: &quot; &lt;&lt; attendees.size()
        &lt;&lt; '\n';
      for (auto m : {meal::breakfast,
                   meal::lunch, meal::dinner}) {
        std::cout &lt;&lt; ' ' &lt;&lt; m &lt;&lt; &quot;: &quot; &lt;&lt;
          count(attendees, m);
      }
      std::cout &lt;&lt; '\n';
      return 0;
    }
    catch (const std::exception &amp;ex) {
      std::cout &lt;&lt; ex.what() &lt;&lt; '\n';
    }
    return -1;
  }</pre>
  
<p>So I recommend to add a newline at the end of the â€˜Totalâ€™ line. From my point of view that would improve the readability of the output. Initialising the ranged based for loop per value is fine, because it is a loop over integral values and there is no performance penalty compared to a <code>const&amp;</code> value.</p>

<p>At the end of the output I would return in case of an overall success a zero and in case of a failure a non-zero value. That is the common behaviour of programs.</p>

<h3>James Holland</h3>

<p>The student has recognised that the meal enumerations have to be distinct and has had the foresight to construct a <code>static_assert</code> in an attempt to enforce that condition. Unfortunately, there are two problems associated with the studentâ€™s code. Firstly, not only do the enumerations have to be unique, they have to contain one, and only one, bit position that has a value of â€˜1â€™. This is so that each bit position within the enumeration is associated with a single meal type. The second problem is that the studentâ€™s <code>static_assert</code> does not fully test for these conditions.</p>

<p>Making the meal enumerations fit the above requirements is simple; just make each a successive integer power of 2. This gives the enumerations <code>breakfast</code>, <code>lunch</code> and <code>dinner</code> the values of 1, 2 and 4 respectively. Enforcing this at compile-time is a little more difficult, however.</p>

<p>The approach I have adopted is to count the number of â€˜1â€™s in each enumeration and to ensure it is equal to one. I have written a <code>constexpr</code> function to do this. Then, to ensure each enumeration is unique, I â€˜orâ€™ all the enumerations and compare the result with the number of enumerations I am â€˜orâ€™ing, in this case, three. Thanks to <code>constexpr</code>, all this is done at compile-time. </p>

<pre class="programlisting">
  // Count the number of 1 bits.
  constexpr size_t number_of_one_bits(
    const meal &amp; m)
  {
    using meal_type =
      typename std::underlying_type_t&lt;meal&gt;;
    size_t number_of_ones = 0;
    for (size_t bit_position = 0;
         bit_position &lt;= 8 * sizeof (meal_type);
         ++bit_position)
    {
      if (static_cast&lt;meal_type&gt;(m) &amp; 
        (1L &lt;&lt; bit_position))
      {
        ++number_of_ones;
      }
    }
    return number_of_ones;
  }
  static_assert(
    number_of_one_bits(meal::breakfast) == 1 &amp;&amp;
    number_of_one_bits(meal::lunch) == 1 &amp;&amp;
    number_of_one_bits(meal::dinner) == 1 &amp;&amp;
    number_of_one_bits(meal::breakfast |
      meal::lunch | meal::dinner) == 3,
    &quot;Meal enumerations are not distinct.&quot;);</pre>
	
<p>Finally, I am not sure how the student intended to signal to the program that all attendeesâ€™ meal requirements have been entered. I have amended the software so that a blank line will bring things to a satisfactory close by employing <code>line.empty()</code> as shown below.</p>

<pre class="programlisting">
  while (std::getline(is, line), !line.empty())</pre>
  
<h3>Jason Spencer</h3>

<p>The basic problem with the code is that the <code>meal</code> enum is being used as a bit mask but actually expresses a bit position. Enum entries (scoped and unscoped) are assigned values which increment by one from the previous entry, starting from 0 for the first entry, unless the value is explicitly specified. So in the code <code>meal::breakfast</code> has a value of 0 (0000b), <code>meal::lunch</code> a value of 1 (0001b), and <code>meal::dinner</code> a value of 2 (0010b). I believe the intent of the programmer is to use the enum as a bitmask where every enum value has a different single bit set, so in this case the least significant bit (LSB) should signify breakfast, the second LSB lunch and the third LSB dinner â€“ the values of which should be 0001b, 0010b, 0100b. The simple solution would be to make the enum:</p>

<pre class="programlisting">
  enum class meal : int { breakfast = 1,
    lunch = 2, dinner = 4, };</pre>
	
<p>or</p>

<pre class="programlisting">
  enum class meal : int { breakfast = 1 &lt;&lt; 0,
    lunch = 1 &lt;&lt; 1, dinner = 1 &lt;&lt; 2, };</pre>
	
<p>My preferred solution would be to keep the enum the way it is, consider it a bit position rather than a bitmask, and wherever the meal bits are set or tested use <code>(1 &lt;&lt; meal)</code> instead of just <code>meal</code>.</p>

<p>But Iâ€™ll come back to the design later. There are other problems in the code, in order of the listings:</p>

<p>meal.h:</p>

<ul>
	<li><code>&lt;iosfwd&gt;</code> should be <code>&lt;iostream&gt;</code> â€“ the stream operators are actually called on istreams and ostreams in the code, so we use more than just forward declarations. Yes, <code>sstream</code> will include <code>iostream</code> anyway, but itâ€™s more robust to include <code>iostream</code> directly if <code>sstream</code> is ever removed...</li>
	
	<li><code>&lt;sstream&gt;</code> should be removed â€“ no <code>stringstreams</code> are used in this file.</li>
	
	<li>Donâ€™t use a signed type for the enum underlying type â€“ whether the enum is a bit position, or a bit mask. You lose one bit for the sign, and if you ever shift the bits you might run into trouble with sign extension. Consider perhaps using an unsigned integer type with a specific size e.g. <code>uint16_t</code>, <code>uint32_t</code> or <code>uint64_t</code> (from the <code>&lt;cstdint&gt;</code> header) â€“ this way itâ€™ll be easier to read your intent with respect to memory usage. And if the mask is ever stored in another struct the issue of padding and storage can be more easily addressed.</li>
	
	<li>Consider renaming the <code>meal</code> enum to <code>meal_t</code> â€“ so then thereâ€™s no confusion between the meal type and the instance (see my <code>(1 &lt;&lt; meal)</code> sentence above).</li>
	
	<li><code>struct names[]</code> should be const as itâ€™s a lookup table which isnâ€™t expected to be changed. And if some code does change it, it may break the enum to string search loops.</li>
	
	<li>the <code>operator&gt;&gt;(istream,meal)</code> overload:
	
		<ul>
			<li>The range for loop doing a linear search should be <code>const auto &amp; p : names</code> instead of <code>auto p : names</code> to prevent an unnecessary copy or an accidental overwrite of <code>p</code>.</li>
			
			<li>Currently, if the meal isnâ€™t found in names then the word is still consumed from the stream, without an error being set, or the meal result variable being updated. The <code>failbit</code> must be set on the <code>istream</code> when the meal isnâ€™t found. This is done with <code>is.setstate(std::ios_base::failbit);</code> Note that <code>setstate</code> could also throw an exception at this point, depending on prior calls to <code>istream::exceptions(..)</code>.</li>
			
			<li>Prefer using <code>istream::sentry</code> to trim whitespace from the input stream and to skip processing if the input stream already has the <code>failbit</code> set.
				<p>You might not be expecting whitespace, but you donâ€™t know where the <code>operator&gt;&gt;</code> overload will be used in future, so donâ€™t rely on it being stripped (although of course <code>is &gt;&gt; name</code> should strip it for you anyway, so this isnâ€™t a hard rule).</p>
			</li>
		</ul>
	</li>
	
	<li>the <code>operator&lt;&lt;(ostream,meal)</code> overload: Nothing is printed if the meal isnâ€™t found in <code>names</code>. Also, if multiple bits are set then all recognised meals would be printed, but without a delimiter. If the bit position is not found in names consider whether an exception should be thrown, or the <code>failbit</code> set on the <code>ostream</code>, or whether you just print the raw bitmask (as a binary string)? The <code>const</code> ref is again missing from the range for loop search.</li>
	
	<li><code>operator+(meal,meal)</code>, <code>operator|(meal,meal)</code> and <code>operator&amp;(meal,meal)</code> would preferably have <code>(const meal, const meal)</code> arguments since weâ€™re not planning on changing them.</li>
	
	<li><code>operator+=(meal &amp; a, meal b)</code> should return an lvalue, so the return type should be <code>meal &amp;</code> and not <code>meal</code>: <code>(meals+=lunch)+=dinner</code> should be valid. The second arg, <code>meal b</code> could be <code>const meal b</code> as we donâ€™t expect to change it.</li>
	
	<li>In the enum manipulation functions (that is the overloads of +, +=, |, &amp;) â€“ Iâ€™d strongly advise against hardcoding the int type into the operation â€“ consider
	<pre class="programlisting">
      meal(static_cast&lt;
        std::underlying_type&lt;meal&gt;::type&gt;(a)+...)</pre>
		<p>instead of <code>meal(int(a)+...)</code> â€“ this way if you change the enumâ€™s underlying type your arithmetic wonâ€™t break and thereâ€™s much less maintenance. C++14 has the slightly shorter <code>std::underlying_type_t&lt;meal&gt;</code> over C++11â€™s <code>std::underlying_type&lt;meal&gt;::type</code>.</p>
	</li>
	
	<li>The <code>static_assert</code> test isnâ€™t perfect â€“ it wouldnâ€™t catch the enum values set to { breakfast = 0, lunch = 0, dinner = 0, }. Thereâ€™s also a question over what distinct means â€“ unique values or no overlapping set bits? This seems to test for no-overlapping bits, so adding a fourth meal <code>{ breakfast, lunch, dinner, beer }</code> (i.e. as a bit position enum, and not the shifted bit mask enum) would cause the assert to fail. Thereâ€™s also no equivalent test that <code>::name</code> in <code>names[]</code> are unique, although that might be overkill. Some might argue the test of uniqueness in the enum is overkill.</li>
</ul>

<p>meals.cpp:</p>

<ul>
	<li><code>#include &lt;string&gt;</code> and <code>#include &lt;sstream&gt;</code> are missing. Thereâ€™s no compilation error because they were already included in <span class="filename">meals.h</span>, but if that ever changes (<code>sstream</code> should be dropped from meals.h anyway), itâ€™s best to include here.</li>
	
	<li>consider renaming <code>attendee</code> type to <code>attendee_t</code> to prevent confusion with an instance.</li>
	
	<li><code>attendee::name</code> could be <code>const</code> as thereâ€™s no obvious use case for changing the name after the struct is created.</li>
	
	<li>in <code>get_attendees(..)</code>:
		
		<ul>
			<li>Perhaps consider a rename to better express that meals are also read? Maybe <code>read_attendees_meals</code>? <code>get</code> usually implies an accessor, not a stream reader.</li>
			
			<li>Regarding the initialisation of meal and meals in <code>meal meal, meals{};</code>: the <code>meal</code> variable is uninitialised, while <code>meals</code> is initialised to the default value, which <em>should</em> be 0. Perhaps consider initialising to 0 explicitly, since thatâ€™s what we want in an empty mask. If <code>iss &gt;&gt; meal</code> cannot find the meal in names it wonâ€™t update the meal variable â€“ and then meals will either be corrupted by the uninitialised meal, or will have another meal added of the value of the previously read meal (which complicates things even more when you consider the next point).</li>
			
			<li>The use of arithmetic add to add a meal in <code>operator+=</code> called by <code>meals += meal;</code> would mean that adding two lunches would become a single dinner (easy to do since we donâ€™t test for duplicates, or report errors). Thatâ€™s wrong.</li>
		</ul>
	</li>
	
	<li><code>std::istream &amp;operator&gt;&gt;(std::istream &amp;is, meal &amp;m)</code> doesnâ€™t set the istreamâ€™s fail bit if the meal isnâ€™t recognised, so <code>get_attendees(std::istream &amp;is)</code> wonâ€™t catch unknown meals. Worse still the <code>meal</code> variable in <code>get_attendees</code> is uninitialised and may now not be set in the read, while still being â€˜insertedâ€™ into meals.
	
		<ul>
			<li>There is no testing whether the read value for <code>meal</code> is already set in <code>meals</code>.</li>
		</ul>
	</li>
	
	<li>In<code> main()</code>:
	
		<ul>
			<li>The main function is a special case when it comes to return values in that when there is no return statement an implicit <code>return 0;</code> is added (3.6.1.5 of [1]). In the case of a function-try-block when the function is <code>main</code> the compiler should do this at the end of the <code>try</code> clause.
			
				<p>However, when reaching the end of the <code>catch</code> clause in the function-try-block the behaviour is equivalent to a return with no argument (15.3.14 of [1]), and therefore in this case the exit code is undefined. An explicit <code>return 1;</code> statement should be added to the end of the catch clause.</p>
			</li>
			<li>Rename <code>count(..)</code> to <code>count_meals(..)</code> â€“ a function called â€˜countâ€™ could count anything, and could be confused with <code>std::count</code>. By the way â€“ <code>count_meals</code> could easily be implemented with <code>std::count_if</code>:
<pre class="programlisting">
     size_t count_meals(const attendees_t a,
       const meal m) {
       return std::count_if( std::begin(a),
         std::end(a), [ m ] (
           const attendees_t::value_type &amp; item ) {
            return (item.meals &amp; m);
       });
     }</pre>
			</li>
			
			<li>when outputting the meals in the <code>for</code> range loop an <code>initialiser_list</code> of enums is used â€“ this is yet another location to update if the enum list is ever changed. Unless a specific order of meals output is required consider using the enum values in <code>names[]</code>:

<pre class="programlisting">
        for (const auto &amp; mn : names )
          std::cout &lt;&lt; ' ' &lt;&lt; mn.name &lt;&lt;  &quot;: &quot;
            &lt;&lt; count_meals ( attendees, mn.value );</pre>
			</li>
		</ul>
	</li>
</ul>

<p>In terms of general design:</p>

<ul>
	<li>If new meals are ever added to the <code>meal</code> enum in <span class="filename">meal.h</span> there are four places that need to be updated â€“ the enum, names, the <code>static_assert</code> and the list in <code>main</code>. Consider grouping at least the first three in the header file for easier updating.</li>
	
	<li>Consider changing the output text to say <em>Number of guests:</em> instead of <em>Total:</em> as the latter could be interpreted as the total number of meals.</li>
	
	<li>Consider moving the enum-to-string and string-to-enum mapping to two new functions â€“ itâ€™ll make testing easier, the code will be self documenting, error handling can be made cleaner and the code may be reused elsewhere. These could be methods in <code>attendee_t</code>, although ideally the responsibility would be put in a new <code>meal_t</code> class alongside other helper functions and tests.</li>
	
	<li>in <code>get_attendees(..)</code> consider splitting the stream reading from the input parsing â€“ in the future the reading and parsing can then change independently. Meals and attendees can also then be parsed from a string, without having to create a <code>stringstream</code> object.</li>
	
	<li>Although itâ€™s syntactically sugary, Iâ€™d consider dropping the enum +, +=, |, &amp; overloads â€“ since weâ€™re going to the trouble of naming the meals and having an enum for them, why confuse things by using cryptic symbols to manipulate them? <code>meals += meal</code> might be more intuitive than <code>meals |= meal</code>, but also possibly wrong. And is the <code>meal</code> enum type (meal, singular) a valid place to hold multiple meals (as the superposition of meals in a bitfield) ? The merged value is no longer one of the listed enum tokens, and is that conceptually still a meal?
	
		<p>Do we even need both <code>operator|</code> and <code>operator+</code>? If itâ€™s just used for the <code>static_assert</code> then do the addition there rather than making a user think itâ€™s valid for general use â€“ an API is as much about preventing users from doing things, as it is about facilitating things.</p>
	</li>
</ul>

<p>I see four points for further investigation:</p>

<h4>Information encoding</h4>

<p>Do we need a bitmask? Yes, itâ€™s very memory efficient, but it has a limited and fixed number of available flags that are stored in it. If the meal names are hard-coded into an enum each bit field must have a given meaning at compile time. What if new meals are introduced, or the meals of multiple days need encoding in the future? a re-write and re-compile is needed (making sure to catch all four places that need the enum list needs to be updated).</p>

<p>My preferred design is to take a list of meals on the command line, and for each input line either put the meals as strings in an <code>std::unordered_set</code>, or an <code>std::unordered_multiset</code> (if in the future you want to allow multiple instances of a meal), without a bitmask. Or read the meal names as strings and directly increment a map like <code>std::unordered_map&lt;std::string, size_t&gt; meal_tally</code>;</p>

<p>Alternatively, encode the meals (the valid values of which are again specified on the command line) into a <code>std::bitset</code> (youâ€™d need to specify a compile time limit on the number of meal options) or a <code>std::vector&lt;bool&gt;</code>. You have the meal names on the command line so can easily map bit positions to and from meal names. The ordering of meals on the command line can also specify the output ordering.</p>

<p>The drawback of dynamically specifying names is that if the bitmask is ever serialised as an integer the bit position meanings must be encoded separately.</p>

<h4>Bitmask use</h4>

<p>I would urge caution on using the enum type youâ€™ve created to represent multiple meals as a bitmask. Their superposition has a different meaning to the original enums, and possibly has a conflicting absolute value. If you do want to use bitmasks, and you want the bit meaning to be specified at compile time as an enum, then use the enum as a bit position. Make it a scoped enum with an underlying type that is an unsigned integer. Have a typedef specifying an unsigned integer type which is called <code>mealset_t</code> (for the actual bitmask), or use an <code>std::bitset</code>, since the latter will deal with the bit positions and offsets for you. But donâ€™t use the <code>meal</code> enum type as a bitmask type, because youâ€™d be killing the meaning.</p>

<p>To get an idea of how an enum bitmask could be implemented have a look at 17.5.2.1.3 in <a href="#[1]">[1]</a>.</p>

<h4>enum management</h4>

<p>C++ has very limited introspection, so you canâ€™t at runtime convert an enum entry into a string with the human-readable name, and you canâ€™t iterate over the enum values, nor even get the number of entries. Enums are just a bunch of scoped, or unscoped, constants. You could, however do things like:</p>

<pre class="programlisting">
  enum class meal_t : uint32_t { breakfast,
    lunch, dinner, leftovers, NUM_MEALS };
  const char * meal_names[] = { &quot;breakfast&quot;,
    &quot;lunch&quot;, &quot;dinner&quot;, &quot;leftovers&quot; };
  static_assert(
    std::size(meal_names)==NUM_MEALS);</pre>

<p>which is similar to what the student did with <code>struct names[]</code>, but this suffers from poor maintenance, so you could get a little hacky with Boost.Preprocessor <a href="#[2]">[2]</a> and use the compiler pre-processor to automate the code generation:</p>

<pre class="programlisting">
  #include &lt;boost/preprocessor/seq/for_each.hpp&gt;
  #define STRINGIFYADDCOMMA_(s) #s,
  #define STRINGIFY_ADD_COMMA(r, data, elem)\
    STRINGIFYADDCOMMA_(elem)
  #define COMMAIFY(r, data, elem) elem, 
  #define PREFIX_COMMA(r, data, elem)\
    data::elem, using utype = uint32_t;
  
  #define MEALS_SEQ\
    (breakfast)(lunch)(dinner)(beer)(icecream)
  enum class meal_t : utype {
    BOOST_PP_SEQ_FOR_EACH( COMMAIFY, DUMMY, 
  MEALS_SEQ)
  };
  constexpr meal_t allmeals [] = {
    BOOST_PP_SEQ_FOR_EACH( PREFIX_COMMA, 
    meal_t, MEALS_SEQ)
  };
  const char * meal_names[]= {
    BOOST_PP_SEQ_FOR_EACH( STRINGIFY_ADD_COMMA, 
      DUMMY, MEALS_SEQ)
  };</pre>

<p>Itâ€™s somewhat of a mess, I know, and the code is a little difficult to read, but to iterate over all <code>meal</code> enums you just iterate over <code>allmeals</code>, to map names, use <code>meal_names[]</code>, to get number of meal types use <code>std::size(allmeals)</code>. And if you need to add new meals, you just add them to MEALS_SEQ and the rest is automatically generated. In GCC you an use the -E switch to see the output of the pre-processor.</p>

<p>Or you could just use a library like Better Enums <a href="#[3]">[3]</a>.</p>

<h4>iostream overloading</h4>

<p>If youâ€™ve overloaded a stream operator then there are a number of expectations. The expectations are in regard to exception handling and error reporting. As mentioned already the <code>istream</code>â€™s <code>failbit</code> must be set if formatted input is expected and it is a different format. Further, the streams and data must be left in a consistent state. Most formatted stream overloads leave, on bad input, the stream with the <code>failbit</code> set, no update of the variable, but possibly some characters taken from the input stream. This is a basic exception guarantee, and a strong guarantee would be hard or impossible to do with a stream (it may not be possible to roll back the underlying buffer or look-ahead far enough). All the details are covered in <a href="#[4]">[4]</a> and it is probably the go-to book for IOStreams â€“ although the book is a little dated, the principles are all there.</p>

<p>Itâ€™s a good exercise in stream use, but instead of the overloads Iâ€™d recommend writing string to enum conversion functions and leave the I/O to the enum user.</p>

<p>In terms of further reading, apart from what is already mentioned above, <a href="#[5]">[5]</a> may be a useful reference to the state of streams (section 15.4) and exception use (section 15.4.4), as well as sentry objects (section 15.5.4) and <code>std::bitset</code> (section 12.5). In fact section 12.5.1 has an example use of an enum to specify bit position in a bitset used as a bitmask.</p>

<p>Of course, you could also implement the whole thing about two orders of magnitude faster in awk:</p>

<pre class="programlisting">
echo -e &quot;Roger breakfast lunch\nJohn lunch dinner\nPeter dinner&quot; | awk 
'{ for(i=2;i&lt;=NF;++i) ++cnt[$i] } END { printf &quot;Guests: &quot; NR; for (i in 
cnt) printf &quot; &quot; i &quot;: &quot; cnt[i]; printf&quot;\n&quot;; }'</pre>

<h4>References</h4>

<p class="bibliomixed"><a id="[1]"></a>[1]	<em>Working Draft, Standard for Programming Language C++</em>, n4296, 2014-11-19</p>

<p class="bibliomixed"><a id="[2]"></a>[2]	<a href="http://www.boost.org/doc/libs/release/libs/preprocessor/">http://www.boost.org/doc/libs/release/libs/preprocessor/</a></p>

<p class="bibliomixed"><a id="[3]"></a>[3]	<a href="http://aantron.github.io/better-enums/">http://aantron.github.io/better-enums/</a></p>

<p class="bibliomixed"><a id="[4]"></a>[4]	<em>Standard C++ IOStreams and Locales: Advanced Programmerâ€™s Guide and Reference</em> by Angelika Langer and Klaus Kreft, Addison Wesley, 1st edition (31 Jan. 2000), ISBN 0321585585</p>

<p class="bibliomixed">[5]<a id="[5]"></a>	<em>The C++ Standard Library: A Tutorial and Reference 2nd Edition </em>by Nicolai M. Josuttis, Addison-Wesley, 25 May 2012 ISBN 0132977737</p>

<h2>Commentary</h2>

<p>The basic problem in the critique â€“ that of using an enumeration to contain a set of values â€“ is one that crops up in various guises. I would suggest that defining arithmetic operations on an enumeration is a category error.</p>

<p>While, as noted in some of the critiques, use of an enum is very efficient in terms of data storage it does have some other issues with usability. I suspect data storage is unlikely to be a serious problem for this program so I would probably recommend using an alternative design.</p>

<p>It might be worth exploring <code>std::bitset </code>as this already provides the logical operators, but the simplest design might just be to use a <code>std::set</code> of enumeration values (or even of strings) unless and until performance or memory use is a constraint.</p>

<p>Unfortunately, C++ does not provide any assistance with ensuring that enumerated values used as a bitmask are â€˜saneâ€™ (each defines a single bit with no overlaps). C# has an attribute (<code>Flags</code>) which at first sight looks useful, but it does not affect nor check the values in the enum.</p>

<p>Another problem with bitmasks is that of the detection of the â€˜no bits setâ€™ case. I recall when Microsoft Windows added a new value to the bitmask of file attributes, <code>FILE_ATTRIBUTE_NORMAL</code>, which is a simulated attribute that is set when no other attributes are set. The intent was that the â€˜no flags setâ€™ case could be detected by checking for this â€˜specialâ€™ bit, but its existence caused a number of other problems and the need in some cases to special-case this value. </p>

<h2>The Winner of CC 107</h2>

<p>All the critiques that engaged with the code identified the fundamental problem with a bitmask value for <code>breakfast</code> of <code>0</code>. Jasonâ€™s approach of keeping the implicit assignment of enum values and using bit shifting operations could a good way to proceed as it works with the flow of the language idioms; Iâ€™d probably want to see the bit shifting encapsulated to avoid confusion for the user.</p>

<p>While combining enumeration values with logical â€˜orâ€™ can produce values that are not in the list of named values this is not a problem, syntactically anyway, in C++ as the standard is careful to define the valid range of an enumeration to include these unnamed values. The danger of converting to the underlying type is that type safety is lost.</p>

<p>Jasonâ€™s point about the number of places to change if a new meal type were added is a good teaching point to make to the author of the code. These sort of hidden dependencies in code bases make changes significantly harder, and learning to avoid creating them in the first place is good practice.</p>

<p>I have a great deal of sympathy with Russelâ€™s approach to the problem (echoed by Jim as well) that this problem does not seem to be a natural fit for the language used.</p>

<p>As Titus Winters pointed out in his keynote that this yearâ€™s CppCon, one of the oddities of programming is that the lifetime of a program can vary by many orders of magnitude. <em>Efficiency</em> (whatever that means) must factor in the cost of writing and modifying the program; since the author here states they are writing a program for a one-off event the time spent developing the program is likely to significantly exceed the total time spent executing it. Ease of development then becomes very significant. So Iâ€™m not persuaded that using Boost.Preprocessor is a good solution to this particular problem as I suspect that might increase development time!</p>

<p>I was unable to explain Felixâ€™s problem with requiring a check on <code>line.empty()</code> â€“ perhaps someone more experienced with the internals of the Mac C++ runtime can explain this? (The extra check does no harm however, and may even make the intent clearer.)</p>

<p>Several people mentioned the need to take care when overloading streaming operators to ensure the flags are set correctly, especially on input. In many cases this happens incidentally, as a call inside the implementation of the operator fails and sets the flags; this critique demonstrates one of the cases where a fully fledged solution needs to ensure the <code>failbit</code> is set manually on error.</p>

<p>Overall I am awarding Jason the prize for this critique as I thought he both covered the presenting problems well but also gave some other good suggestions for the author to improve their skill at programming.</p>

<h2>Code Critique 108</h2>

<h3>(Submissions to scc@accu.org by Dec 1st)</h3>

<p class="blockquote"><code>Iâ€™ve got a problem with an extra colon being produced in the output from a program. Iâ€™ve stripped down the files involved in the program a fair bit to this smaller example. Here is what the program produces:</code></p>

<pre class="programlisting">
    test_program Example &quot;With space&quot;
    1:: 1001:Example
    2:: &quot;1002:With space&quot;</pre>

<p class="blockquote">I canâ€™t see where the <em>two</em> colons after each initial number come from as I only ask for <em>one</em>.</p>

<p>Please can you help the programmer find the cause of their problem and suggest some other possible things to consider about their program.</p>

<ul>
	<li>Listing 3 contains <span class="filename">record.h</span></li>
	<li>Listing 4 contains <span class="filename">record.cpp</span></li>
	<li>Listing 5 contains <span class="filename">escaped.h</span></li>
	<li>Listing 6 contains <span class="filename">test_program.cpp</span></li>
</ul>

<table class="sidebartable">
	<tr>
		<td>
			<pre class="programlisting">
namespace util
{
  class Record {
  public:
    Record(uint64_t id,
      std::string value = {});
    std::string to_string() const;
    // other methods elided
  private:
    uint64_t const id;
    std::string value;
  };
  inline
  std::string to_string(Record const &amp;r)
  {
    return r.to_string();
  }
}
			</pre>
		</td>
	</tr>
	<tr>
		<td class="title">Listing 3</td>
	</tr>
</table>

<table class="sidebartable">
	<tr>
		<td>
			<pre class="programlisting">
#include &lt;cstdint&gt;
#include &lt;sstream&gt;
#include &lt;string&gt;

#include &quot;record.h&quot;

util::Record::Record(uint64_t id, std::string value)
  : id(id), value(value) {}

std::string util::Record::to_string() const
{
  std::ostringstream oss;
  oss &lt;&lt; id &lt;&lt; &quot;:&quot; &lt;&lt; value;
  return oss.str();
}

			</pre>
		</td>
	</tr>
	<tr>
		<td class="title">Listing 4</td>
	</tr>
</table>

<table class="sidebartable">
	<tr>
		<td>
			<pre class="programlisting">
#pragma once
#include &lt;string&gt;

namespace util
{
  // provide 'escaped' textual representation
  // of value
  // - any double quotes need escaping with \    
  // - wrap in double quotes if has any spaces
  template &lt;typename T&gt;
  std::string escaped_text(T t)
  {
    using namespace std;
    
    auto ret = to_string(t);
    for (std::size_t idx = 0;
      (idx = ret.find(idx, '&quot;')) !=
        std::string::npos;
      idx += 2)
    {
      ret.insert(idx, &quot;\\&quot;, 1);
    }
    if (ret.find(' ') != std::string::npos)
    {
      ret = '&quot;' + ret + '&quot;';
    }
    return ret;
  }
}
			</pre>
		</td>
	</tr>
	<tr>
		<td class="title">Listing 5</td>
	</tr>
</table>

<table class="sidebartable">
	<tr>
		<td>
			<pre class="programlisting">
#include &lt;cstdint&gt;
#include &lt;iostream&gt;
#include &quot;record.h&quot;
#include &quot;escaped.h&quot;

using namespace util;

template &lt;typename K, typename V&gt;
void output(K key, V value)
{
  std::cout &lt;&lt; escaped_text(key) &lt;&lt; &quot;: &quot;
    &lt;&lt; escaped_text(value) &lt;&lt; '\n';
}
 
int main(int argc, char **argv)
{
  static uint64_t first_id{1000};
  for (int idx = 1; idx != argc; ++idx)
  {
    Record r{++first_id, argv[idx]};
    output(idx, r);
  }
}
			</pre>
		</td>
	</tr>
	<tr>
		<td class="title">Listing 6</td>
	</tr>
</table>

<p>You can also get the current problem from the accu-general mail list (next entry is posted around the last issueâ€™s deadline) or from the ACCU website (<a href="http://accu.org/index.php/journal">http://accu.org/index.php/journal</a>). This particularly helps overseas members who typically get the magazine much later than members in the UK and Europe.</p>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
