ecto
except.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011, Willow Garage, Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * * Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * * Neither the name of the Willow Garage, Inc. nor the names of its
14  * contributors may be used to endorse or promote products derived from
15  * this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  */
29 #pragma once
30 
31 #define ECTO_EXCEPTION_TAG_NAMES \
32  (from_typename)(to_typename)(from_key)(to_key)(from_cell) \
33  (to_cell)(cpp_typename)(pyobject_repr)(actualtype_hint)(spore_typename) \
34  (diag_msg)(actualkeys_hint)(tendril_key)(cell_name)(cell_type)(function_name) \
35  (hint)(which_tendrils)(prev_typename)(cur_typename)(type) \
36  (what)(when)
37 
38 #define ECTO_EXCEPTIONS \
39  (TypeMismatch)(ValueNone)(ValueRequired)(NonExistant) \
40  (FailedFromPythonConversion)(TendrilRedeclaration)(CellException) \
41  (NotConnected)(AlreadyConnected)(NullTendril)
42 
43 // these are to speed up the preprocessor metaprogramming
44 # ifndef BOOST_PREPROCESSOR_CONFIG_LIMITS_HPP
45 # define BOOST_PREPROCESSOR_CONFIG_LIMITS_HPP
46 #
47 # define ECTO_PP_ITERLIMIT 22
48 # define BOOST_PP_LIMIT_MAG ECTO_PP_ITERLIMIT
49 # define BOOST_PP_LIMIT_TUPLE 25
50 # define BOOST_PP_LIMIT_DIM 3
51 # define BOOST_PP_LIMIT_REPEAT ECTO_PP_ITERLIMIT
52 # define BOOST_PP_LIMIT_WHILE ECTO_PP_ITERLIMIT
53 # define BOOST_PP_LIMIT_FOR ECTO_PP_ITERLIMIT
54 # define BOOST_PP_LIMIT_ITERATION ECTO_PP_ITERLIMIT
55 # define BOOST_PP_LIMIT_ITERATION_DIM 2
56 # define BOOST_PP_LIMIT_SEQ ECTO_PP_ITERLIMIT
57 # define BOOST_PP_LIMIT_SLOT_SIG 10
58 # define BOOST_PP_LIMIT_SLOT_COUNT 5
59 #
60 # endif
61 
62 #include <Python.h>
63 #include <boost/version.hpp>
64 #include <stdexcept>
65 #include <string>
66 #include <map>
67 #include <ecto/config.hpp>
68 #include <ecto/util.hpp>
69 #include <boost/optional.hpp>
70 
71 #include <boost/exception/exception.hpp>
72 #include <boost/exception/info.hpp>
73 
74 #include <boost/preprocessor/cat.hpp>
75 #include <boost/preprocessor/stringize.hpp>
76 #include <boost/preprocessor/seq/for_each.hpp>
77 
78 #pragma once
79 namespace ecto
80 {
81  namespace except
82  {
83  namespace detail {
84  template <class T>
85  struct wrap { };
86  }
87 
89  : public ::boost::exception_detail::error_info_container
90  {
91  typedef ::boost::exception_detail::type_info_ type_info_;
92  typedef ::boost::exception_detail::error_info_base error_info_base;
93 
94  //
95  // hacks for boost::exception implementation details that are
96  // moving around.
97  //
98 #if defined(ECTO_EXCEPTION_SHARED_POINTERS_ARE_CONST)
99  typedef boost::shared_ptr<error_info_base const> error_info_base_ptr;
100  typedef void diagnostic_information_arg_t;
101 #else
102  typedef boost::shared_ptr<error_info_base> error_info_base_ptr;
103  typedef const char* diagnostic_information_arg_t;
104 #endif
105 
106  public:
107 
109 
110  ~error_info_container_impl() throw();
111 
112  void
113  set(error_info_base_ptr const & x,
114  type_info_ const & typeid_);
115 
116  error_info_base_ptr
117  get( type_info_ const & ti ) const;
118 
119  char const * diagnostic_information(
120 #if defined(ECTO_EXCEPTION_DIAGNOSTIC_IMPL_TAKES_CHARSTAR)
121  char const*
122 #endif
123  ) const;
124  private:
125 
126  friend class boost::exception;
127 
128  typedef std::map<std::string, error_info_base_ptr>
131  mutable std::string diagnostic_info_str_;
132  mutable int count_;
133 
134  void add_ref() const;
135 #if defined(ECTO_EXCEPTION_RELEASE_RETURNS_VOID)
136  void release() const;
137 #else
138  bool release() const;
139 #endif
140 #if defined(ECTO_EXCEPTION_HAS_CLONE)
141  ::boost::exception_detail::refcount_ptr< ::boost::exception_detail::error_info_container> clone() const;
142 #endif
143 
144  };
145 
146  struct EctoException : virtual std::exception, virtual boost::exception
147  {
148  EctoException();
149  virtual const char* what() const throw();
150  };
151 
152  // here, what() actually returns the type name, the errinfo tag stuff
153  // is used for the more illuminating error information
154 #define ECTO_DECLARE_EXCEPTION(r, data, T) \
155  struct T : virtual EctoException \
156  { \
157  const char* what() const throw(); \
158  };
159 
161 
162  std::string diagnostic_string(const EctoException&);
163 
164  boost::optional<std::string> diagnostic_string(const EctoException& e,
165  const std::string& tag);
166 
167 #define ECTO_EXCEPTION_TAG_DECL(r, data, NAME) \
168  struct BOOST_PP_CAT(tag_, NAME); \
169  typedef ::boost::error_info<detail::wrap<BOOST_PP_CAT(tag_, NAME)>, \
170  std::string> NAME; \
171 
173 
174  }
175 }
176 
177 namespace boost {
178 
179 #if defined(ECTO_EXCEPTION_TAG_TYPE_NAME_RETURNS_STRING)
180 # define ECTO_EXCEPTION_TAG_TYPE_NAME_RETURN_T std::string
181 #else
182 # define ECTO_EXCEPTION_TAG_TYPE_NAME_RETURN_T const char*
183 #endif
184 
185 #define ECTO_EXCEPTION_TAG_TYPE_NAME_DECL(r, data, NAME) \
186  template <> inline \
187  ECTO_EXCEPTION_TAG_TYPE_NAME_RETURN_T \
188  tag_type_name< ::ecto::except::detail::wrap< BOOST_PP_CAT(::ecto::except::tag_, NAME)> >() { \
189  return BOOST_PP_STRINGIZE(NAME); \
190  }
192 
193  template <class E,class Tag,class T>
194 #if ((BOOST_VERSION / 100) % 1000) <= 42
195  E const &
196 #else
197  typename enable_if<exception_detail::derives_boost_exception<E>,E const &>::type
198 #endif
199  operator<<( E const & x,
200  error_info< ::ecto::except::detail::wrap<Tag>, T> const & v );
201 
202 }
203 
::boost::exception_detail::error_info_base error_info_base
Definition: except.hpp:92
const ecto::tendril & get(const std::string &type_name)
#define ECTO_EXCEPTIONS
Definition: except.hpp:38
Definition: std_map_indexing_suite.hpp:20
#define ECTO_EXCEPTION_TAG_DECL(r, data, NAME)
Definition: except.hpp:167
Definition: except.hpp:146
#define ECTO_EXCEPTION_TAG_TYPE_NAME_DECL(r, data, NAME)
Definition: except.hpp:185
std::string diagnostic_info_str_
Definition: except.hpp:131
const char * diagnostic_information_arg_t
Definition: except.hpp:103
std::map< std::string, error_info_base_ptr > error_info_map
Definition: except.hpp:129
Definition: parameters.hpp:11
#define ECTO_EXCEPTION_TAG_NAMES
Definition: except.hpp:31
int count_
Definition: except.hpp:132
BOOST_PP_SEQ_FOR_EACH(ECTO_DECLARE_EXCEPTION,~, ECTO_EXCEPTIONS)
error_info_map info_
Definition: except.hpp:130
Definition: except.hpp:85
std::string diagnostic_string(const EctoException &)
#define ECTO_DECLARE_EXCEPTION(r, data, T)
Definition: except.hpp:154
::boost::exception_detail::type_info_ type_info_
Definition: except.hpp:91
E const & operator<<(E const &x, error_info< ::ecto::except::detail::wrap< Tag >, T > const &v)
boost::shared_ptr< error_info_base > error_info_base_ptr
Definition: except.hpp:102