/* Voorbeeldcode behorende bij het college "Programmeertechnieken",
 * LIACS, Universiteit Leiden.
 */

#include <iostream>
#include <exception>
#include <vector>


static void voorbeeld1(void)
{
  /* Doe iets nuttigs ... */
  /* Oei, het gaat helemaal fout! */
  throw 13;

  /* meer code ... */
}

static void voorbeeld2(void)
{
  /* Probeer een bestand te openen. */
  throw std::exception();

  /* Hier gewoon verder als het was gelukt */
}


/* We kunnen ook zelf exceptie objecten maken waarin we specifieke
 * informatie kunnen stoppen.
 */
class OnzeException: public std::exception
{
  virtual const char* what() const noexcept
  {
    return "Sorry, we konden het bestand niet openen.";
  }
};

static void voorbeeld3(void)
{
  throw OnzeException();
}

/* Voorbeeld met diepe nesting van functie-aanroepen. */
static void voorbeeld41(void)
{
  // ...
}

static void voorbeeld421(void)
{
  throw std::string("Sorry, er ging iets mis ...");
}

static void voorbeeld42(void)
{
  voorbeeld421();
}

static void voorbeeld43(void)
{
  // ...
}

static void voorbeeld4(void)
{
  voorbeeld41();
  voorbeeld42();
  voorbeeld43();
}

/* Voorbeeld met STL */
static void voorbeeld5(void)
{
  /* Kan geen vector met negatieve lengte maken */
  std::vector<double> A(-1);

  A[0] = 1234;
}

int main(void)
{
  try
    {
      voorbeeld1();
    }
  catch (int fout)
    {
      std::cerr << "Het ging fout! Fout: "
                << fout << std::endl;
    }

  try
    {
      voorbeeld2();
    }
  catch (std::exception &e)
    {
      std::cerr << "Fout: " << e.what()
                << std::endl;
    }

  try
    {
      voorbeeld3();
    }
  catch (std::exception &e)
    {
      std::cerr << "Fout: " << e.what()
                << std::endl;
    }

  try
    {
      voorbeeld4();
    }
  catch (std::exception &e)
    {
      std::cerr << "Fout: " << e.what()
                << std::endl;
    }
  catch (...)
    {
      std::cerr << "Overige fout"
                << std::endl;
    }

  try
    {
      voorbeeld5();
    }
  catch (std::exception &e)
    {
      std::cerr << "Fout: " << e.what()
                << std::endl;
    }

  return 0;
}