// file      : alt1.cpp
// author    : Boris Kolpackov <boris@kolpackov.net>
// copyright : Copyright (c) 2003 Boris Kolpackov
// license   : http://kolpackov.net/license.html


class Color
{
public:
  static Color const red, green, blue;

  enum Value
  {
    red_l, green_l, blue_l
  };

  Value
  integral () const
  {
    return v_;
  }

  char const*
  label () const;

  friend bool
  operator== (Color const& a, Color const& b)
  {
    return a.v_ == b.v_;
  }

  friend bool
  operator!= (Color const& a, Color const& b)
  {
    return a.v_ != b.v_;
  }

private:
  Color (Value v)
      : v_ (v)
  {
  }

  Value v_;
};

#include <iostream>

Color const
Color::red (Color::red_l),
Color::green (Color::green_l),
Color::blue (Color::blue_l);

namespace
{
  char const* color_labels_[] = {"red", "green", "blue"};
}

char const* Color::
label () const
{
  return color_labels_[v_];
}

std::ostream&
operator<< (std::ostream& o, Color c)
{
  return o << c.label ();
}

using std::cerr;
using std::endl;

void f (Color)
{
  cerr << "color" << endl;
}

void f (int)
{
  cerr << "int" << endl;
}

int
main ()
{
  // 1
  {
    // Color c (red);   // error: red undeclared
    Color c (Color::red);
  }

  // 2
  {
    // Color c;         // error: no default c-tor
    Color c (Color::red);
    c = Color::blue;
  }

  // 3
  {
    Color c (Color::red);
    cerr << c << " " << Color::green << endl;
  }

  // 4
  {
    Color c (Color::red);

    f (c);
    f (Color::red);

    // c + Color::red;  // error: no operator+

    // if (c) {}        // error: no conversion from Color to bool

    if (c == Color::red && c != Color::blue)
    {
      cerr << "ok" << endl;
    }
  }

  // 5
  {
    Color c (Color::red);

    switch (c.integral ())
    {
    case Color::red_l:
      cerr << "r" << endl;
      break;

    case Color::green_l:
      cerr << "g" << endl;
      break;

    case Color::blue_l:
      cerr << "b" << endl;
      break;
    }
  }
}
