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


class Color
{
public:
  enum Value
  {
    red, green, blue
  };

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

  operator Value () const
  {
    return v_;
  }

  operator char const* () const;

private:
  Value v_;
};

#include <iostream>

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

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

std::ostream&
operator<< (std::ostream& o, Color c)
{
  char const* str = c;
  return o << str;
}

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; // prints "red 1"!
  }

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

    f (c);
    f (Color::red); // calls f (int)

    // c + Color::red;  // ambigous operator+ overloading

    if (c) {}        // ok

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

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

    switch (c)
    {
    case Color::red:
      cerr << "r" << endl;
      break;

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

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