summaryrefslogtreecommitdiff
path: root/contrib/utility/Example/ExH/Compound/compound.cpp
blob: 9e042ca9c1e3caec8a8d8b1977f49c27e1adc983 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
// file      : Example/ExH/Compound/compound.cpp
// author    : Boris Kolpackov <boris@kolpackov.net>
// copyright : Copyright (c) 2002-2003 Boris Kolpackov
// license   : http://kolpackov.net/license.html

#include "Utility/ExH/Compound.hpp"
#include "Utility/ExH/System/Exception.hpp"
#include "Utility/ExH/Logic/DescriptiveException.hpp"

// Include some helper converters to allow exception initialization
// with std::ostringstream

#include "Utility/ExH/StringStreamConverter.hpp"

#include <iostream>

using std::cerr;
using std::endl;
using std::string;
using std::ostringstream;

using namespace Utility::ExH;

// Here are our components

class Base
{
public:

  //
  // Exception definitions.
  //

  // Base logic exception class for component.
  class Exception_ {};
  typedef
  Compound <Exception_, Logic::DescriptiveException>
  Exception;

  class InvalidArgument_ {};
  typedef
  Compound <InvalidArgument_, Exception>
  InvalidArgument;

  class NotInitialized_ {};
  typedef
  Compound <NotInitialized_, Exception>
  NotInitialized;

public:

  void
  foo (char const* str) throw (InvalidArgument, NotInitialized)
  {
    // This is just an example.

    if (str == 0)
    {
      throw InvalidArgument ("Base::foo: first parameter is zero.");
    }
    else
    {
      ostringstream ostr;
      ostr << "Base::foo [this = " << this << "]: object is not initialized.";

      throw NotInitialized (ostr);
    }
  }


  // We don't know what implementation may decide to throw so
  // we allow to throw System exception and any logic exception
  // derived from Base::Exception
  virtual void
  vfoo () throw (Exception, System::Exception) = 0;
};

class Derived : public Base
{
public:

  // Define some Derived-specific logic exception.
  class NotImplemented_ {};
  typedef
  Compound <NotImplemented_, Exception>
  NotImplemented;

public:
  virtual void
  vfoo () throw (NotImplemented, System::Exception)
  {
    std::string str ("Derived::vfoo: not implemented yet.");
    throw NotImplemented (str);
  }
};

int
main ()
{
  try
  {

    Derived d;
    Base* pb (&d);

    // We can use generic handler.
    try
    {
      pb->vfoo ();
    }
    catch (Base::Exception const& ex)
    {
      cerr << "Caught Base::Exception: " << ex.what () << endl;
    }


    // Or use more precise control.
    try
    {
      pb->foo ("hello");
    }
    catch (Base::NotInitialized const& ex)
    {
      cerr << "Caught Base::NotInitialized: " << ex.what () << endl;
    }

    // Or use application-level handler.
    pb->foo (0);

  }
  catch (Logic::Exception const& ex)
  {
    cerr << "Caught Logic::Exception: " << ex.what () << endl;
  }
  catch (...)
  {
    cerr << "Caught unknown exception using catch-all handler" << endl;
    return -1;
  }

}
//$Id$