SST/macro
util.h
Go to the documentation of this file.
1 /*
2  * This file is part of SST/macroscale:
3  * The macroscale architecture simulator from the SST suite.
4  * Copyright (c) 2009 Sandia Corporation.
5  * This software is distributed under the BSD License.
6  * Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
7  * the U.S. Government retains certain rights in this software.
8  * For more information, see the LICENSE file in the top
9  * SST/macroscale directory.
10  */
11 
12 #ifndef sprockit_common_util_h
13 #define sprockit_common_util_h
14 
15 #include <sprockit/spkt_config.h>
16 #include <sprockit/errors.h>
17 
18 #if SPKT_HAVE_CPP11
19 #include <functional>
20 #include <tuple>
21 #endif
22 
23 namespace sprockit {
24 
25 template <class Out, class In>
26 Out*
27 __safe_cast__(const char* objname,
28  const char* file,
29  int line,
30  In* in,
31  const char* error_msg = "error")
32 {
33  Out* out = dynamic_cast<Out*>(in);
34  if (!out) {
36  "%s: failed to cast object at %s:%d",
37  error_msg, file, line);
38  }
39  return out;
40 }
41 
42 /**
43  * First entry in VA_ARGS is the obj
44  * Second entry is optional being an error msg
45 */
46 #define safe_cast(type,...) \
47  ::sprockit::__safe_cast__<type>(#type, __FILE__, __LINE__, __VA_ARGS__)
48 
49 #define test_cast(type, obj) \
50  dynamic_cast<type*>(obj)
51 
52 #define known_cast(type,...) \
53  safe_cast(type, __VA_ARGS__)
54 
55 #define interface_cast(type,obj) \
56  dynamic_cast<type*>(obj)
57 
58 template <class maptype, class keytype>
59 const typename maptype::mapped_type&
60 mapget(const maptype& mapobj, const keytype& keyobj, const char* errormsg)
61 {
62  typename maptype::const_iterator it = mapobj.find(keyobj);
63  if (it == mapobj.end()) {
64  spkt_throw_printf(value_error, "could not find entry in map: %s", errormsg);
65  }
66  return it->second;
67 }
68 
69 
70 // Splat a tuple into a function call
71 // Most of the time, you should just use std::bind for this sort of thing,
72 // but you might need it for something...
73 #if SPKT_HAVE_CPP11
74 namespace detail {
75 
76 template<int...>
77 struct integer_meta_sequence
78 {};
79 
80 template<int N, int... S>
81 struct meta_sequence_generator
82  : meta_sequence_generator<N-1, N-1, S...>
83 {};
84 
85 template<int... S>
86 struct meta_sequence_generator<0, S...>{
87  typedef integer_meta_sequence<S...> type;
88 };
89 
90 template <typename Function, typename Tuple, int... S>
91 typename Function::result_type
92 splat_tuple_impl(
93  Function&& func,
94  Tuple&& tup,
95  const integer_meta_sequence<S...>&
96 )
97 {
98  return func(std::get<S>(tup)...);
99 }
100 
101 } // end namespace detail
102 
103 template <typename Tuple, typename Return, typename... Args>
104 Return splat_tuple(std::function<Return(Args...)>&& func, Tuple&& tup)
105 {
106  return detail::splat_tuple_impl(
107  func, tup,
108  typename detail::meta_sequence_generator<std::tuple_size<Tuple>::value>::type()
109  );
110 }
111 
112 #endif
113 
114 
115 // Modal base class
116 //template <typename BaseOf, typename ModeEnum, ModeEnum mode>
117 //class ModalMixin {
118 // protected:
119 // typedef enum { disabled } disabled_t;
120 //
121 // void throw_method_called_in_wrong_mode(
122 // const std::string& method_name
123 // ) const {
124 // spkt_throw_printf(sprockit::illformed_error,
125 // "method %s() of modal base class was called not called in %s mode;"
126 // " it is only valid when called in this mode",
127 // method_name, BaseOf::mode_names[mode]
128 // );
129 // }
130 //
131 // bool disabled_ = false;
132 //
133 // void check_mode(
134 // const std::string& method_name
135 // ) {
136 // if(disabled_) {
137 // throw_method_called_in_wrong_mode(method_name);
138 // }
139 // }
140 //
141 // BaseOf* this_;
142 //
143 //};
144 
145 namespace modal_mixin {
146 
147 typedef enum { disabled } disabled_t;
148 
150  protected:
151 
152  ModalMixinBase() : disabled_(false) { }
153 
154  ModalMixinBase(bool disabled) : disabled_(disabled) { }
155 
156  virtual std::string get_mode_name() const =0;
157  virtual std::string get_baseof_name() const =0;
158 
159  virtual ~ModalMixinBase() { }
160 
162  const std::string& method_name
163  ) const {
165  "method %s() of %s is not valid in %s mode",
166  get_baseof_name().c_str(),
167  get_mode_name().c_str()
168  );
169  }
170 
171  bool disabled_;
172 
174  const std::string& method_name
175  ) const {
176  if(disabled_) {
177  throw_method_called_in_wrong_mode(method_name);
178  }
179  }
180 
181 };
182 
183 } // end namespace modal_mixin
184 
185 #define ASSERT_CORRECT_MODE check_mode(__PRETTY_FUNCTION__);
186 
187 } // end namespace sprockit
188 
189 
190 // Easy delegation to pointer members
191 #if SPKT_HAVE_CPP11
192 #include <utility>
193 #include <cassert>
194 // TODO non-pointer-member version
195 #define SPKT_DELEGATE_ALL_OVERLOADS(method_name, member) \
196  template <typename... __MethArgs> \
197  auto method_name(__MethArgs&&... __in_args) \
198  -> decltype( \
199  member->method_name( \
200  std::forward<__MethArgs>(__in_args)... \
201  ) \
202  ) \
203  { \
204  assert(member != NULL); \
205  return member->method_name( \
206  std::forward<__MethArgs>(__in_args)... \
207  ); \
208  }
209 #define SPKT_DELEGATE_ALL_CONST_OVERLOADS(method_name, member) \
210  template <typename... __MethArgs> \
211  auto method_name(__MethArgs&&... __in_args) const \
212  -> decltype( \
213  member->method_name( \
214  std::forward<__MethArgs>(__in_args)... \
215  ) \
216  ) \
217  { \
218  assert(member != NULL); \
219  return member->method_name( \
220  std::forward<__MethArgs>(__in_args)... \
221  ); \
222  }
223 #else
224 #define SPKT_DELEGATE_ALL_OVERLOADS(method_name, member) \
225  spkt_static_assert(false, "SPKT_DELEGATE_ALL_OVERLOADS requires c++11")
226 #endif
227 
228 #if SPKT_HAVE_CPP11
229 #include <iterator>
230 #include <algorithm>
231 #define spkt_find_if(iterable, param, ...) \
232  std::find_if(iterable.begin(), iterable.end(), \
233  [&](const typename std::iterator_traits<decltype(iterable.begin())>::value_type& param) -> bool \
234  __VA_ARGS__ \
235  )
236 #else
237 #include <sprockit/preprocessor.h>
238 #define spkt_find_if(...) \
239  spkt_static_assert(false, "spkt_find_if() requires c++11")
240 #endif
241 
242 
243 #endif
void check_mode(const std::string &method_name) const
Definition: util.h:173
Out * __safe_cast__(const char *objname, const char *file, int line, In *in, const char *error_msg="error")
Definition: util.h:27
An error indicating some format was not correct.
Definition: errors.h:131
const maptype::mapped_type & mapget(const maptype &mapobj, const keytype &keyobj, const char *errormsg)
Definition: util.h:60
void throw_method_called_in_wrong_mode(const std::string &method_name) const
Definition: util.h:161
#define spkt_throw_printf(exc, template_str,...)
Definition: errors.h:37
Error indicating some internal value was unexpected.
Definition: errors.h:83