00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef CLASP_UTIL_MISC_TYPES_H_INCLUDED
00022 #define CLASP_UTIL_MISC_TYPES_H_INCLUDED
00023
00024 #include <clasp/util/platform.h>
00025 #include <utility>
00026 #include <functional>
00027 #include <algorithm>
00032 namespace Clasp {
00033 class Solver;
00034 struct Model;
00035
00037 struct Event {
00038 enum Subsystem { subsystem_facade = 0, subsystem_load = 1, subsystem_prepare = 2, subsystem_solve = 3 };
00039 enum Verbosity { verbosity_quiet = 0, verbosity_low = 1, verbosity_high = 2, verbosity_max = 3 };
00040 explicit Event(Subsystem sys, uint32 evId, Verbosity verbosity) : system(sys), verb(verbosity), op(0), id(evId) {}
00041 uint32 system : 2;
00042 uint32 verb : 2;
00043 uint32 op : 8;
00044 uint32 id : 16;
00045 static uint32 nextId();
00046 };
00047 template <class T>
00048 struct Event_t : Event {
00049 Event_t(Subsystem sys, Verbosity verb) : Event(sys, id_s, verb) {}
00050 static const uint32 id_s;
00051 };
00052 template <class T> const uint32 Event_t<T>::id_s = Event::nextId();
00054 struct LogEvent : Event_t<LogEvent> {
00055 enum LogType { message = 'M', warning = 'W' };
00056 LogEvent(Subsystem sys, Verbosity verb, LogType t, const Solver* s, const char* what) : Event_t<LogEvent>(sys, verb), solver(s), msg(what) {
00057 op = static_cast<uint32>(t);
00058 }
00059 bool isWarning() const { return op == static_cast<uint32>(warning); }
00060 const Solver* solver;
00061 const char* msg;
00062 };
00064 inline LogEvent message(Event::Subsystem sys, const char* what, const Solver* s = 0) { return LogEvent(sys, Event::verbosity_high, LogEvent::message, s, what); }
00065 template <Event::Verbosity V>
00066 inline LogEvent message(Event::Subsystem sys, const char* what, const Solver* s = 0) { return LogEvent(sys, V, LogEvent::message, s, what); }
00068 inline LogEvent warning(Event::Subsystem sys, const char* what, const Solver* s = 0){ return LogEvent(sys, Event::verbosity_quiet, LogEvent::warning, s, what); }
00070 template <class T>
00071 struct SolveEvent : Event_t<T> {
00072 SolveEvent(const Solver& s, Event::Verbosity verb) : Event_t<T>(Event::subsystem_solve, verb), solver(&s) {}
00073 const Solver* solver;
00074 };
00076 struct ModelEvent : SolveEvent<ModelEvent> {
00077 ModelEvent(const Model& m, const Solver& s) : SolveEvent<ModelEvent>(s, verbosity_quiet), model(&m) {}
00078 const Model* model;
00079 };
00080
00081 template <class ToType, class EvType> const ToType* event_cast(const EvType& ev) { return ev.id == ToType::id_s ? static_cast<const ToType*>(&ev) : 0; }
00082
00083 class EventHandler {
00084 public:
00085 explicit EventHandler(Event::Verbosity verbosity = Event::verbosity_quiet) {
00086 for (uint32 i = 0; i != sizeof(verbosity_)/sizeof(verbosity_[0]); ++i) { verbosity_[i] = static_cast<uint8>(verbosity); }
00087 }
00088 virtual ~EventHandler();
00089 void setVerbosity(Event::Subsystem sys, Event::Verbosity verb) {
00090 verbosity_[sys] = static_cast<uint8>(verb);
00091 }
00092 void dispatch(const Event& ev) {
00093 if (ev.verb <= verbosity_[ev.system]) { onEvent(ev); }
00094 }
00095 virtual void onEvent(const Event& ) {}
00096 virtual bool onModel(const Solver& s, const Model& m) { onEvent(ModelEvent(m, s)); return true; }
00097 private:
00098 EventHandler(const EventHandler&);
00099 EventHandler& operator=(const EventHandler&);
00100 uint8 verbosity_[4];
00101 };
00102
00107
00108 inline unsigned hashId(unsigned key) {
00109 key = ~key + (key << 15);
00110 key ^= (key >> 11);
00111 key += (key << 3);
00112 key ^= (key >> 5);
00113 key += (key << 10);
00114 key ^= (key >> 16);
00115 return key;
00116 }
00117
00118
00119 inline uint64 choose(unsigned n, unsigned k) {
00120 if (k == 0) return 1;
00121 if (k > n) return 0;
00122 if (2 * k > n) { return choose(n, n-k);}
00123 uint64 res = n;
00124 for (unsigned i = 2 ; i <= k; ++i) {
00125 res *= (n + 1 - i);
00126 res /= i;
00127 }
00128 return res;
00129 }
00130
00132
00136 class RNG {
00137 public:
00138 explicit RNG(uint32 seed = 1) : seed_(seed) {}
00139
00141
00147 void srand(uint32 seed) { seed_ = seed; }
00148
00150
00154 uint32 rand() {
00155 return( ((seed_ = seed_ * 214013L + 2531011L) >> 16) & 0x7fff );
00156 }
00157
00159 double drand() {
00160 return this->rand()/static_cast<double>(0x8000u);
00161 }
00162
00164 unsigned irand(unsigned max) {
00165 return static_cast<unsigned>(drand() * max);
00166 }
00167
00168 uint32 seed() const { return seed_; }
00169
00170 uint32 operator()(unsigned max) { return irand(max); }
00171 uint32 operator()() { return rand(); }
00172 private:
00173 uint32 seed_;
00174 };
00175
00177 struct DestroyObject {
00178 template <class T> void operator()(T* p) const { if (p) p->destroy(); }
00179 };
00181 struct DeleteObject {
00182 template <class T> void operator()(T* p) const { delete p; }
00183 };
00185 struct ReleaseObject {
00186 template <class T> void operator()(T* p) const { if (p) p->release(); }
00187 };
00188
00189 struct IsNull {
00190 template <class T> bool operator()(const T& p) const { return p == 0; }
00191 };
00192
00194 template <class T>
00195 struct PairContains {
00196 PairContains(const T& p) : p_(p) {}
00197 bool operator()(const std::pair<T, T>& s) const {
00198 return s.first == p_ || s.second == p_;
00199 }
00200 T p_;
00201 };
00202
00204
00209 template <class C, class P>
00210 void remove_first_if(C& cont, const P& p) {
00211 for (typename C::iterator it = cont.begin(), end = cont.end(); it != end; ++it) {
00212 if (p(*it)) {
00213 *it = cont.back();
00214 cont.pop_back();
00215 return;
00216 }
00217 }
00218 }
00219
00221 template <class T>
00222 struct identity : std::unary_function<T, T>{
00223 T& operator()(T& x) const { return x; }
00224 const T& operator()(const T& x) const { return x; }
00225 };
00226
00227
00229 template <class P>
00230 struct select1st : std::unary_function<P, typename P::first_type> {
00231 typename P::first_type& operator()(P& x) const {
00232 return x.first;
00233 }
00234 const typename P::first_type& operator()(const P& x) const {
00235 return x.first;
00236 }
00237 };
00238
00240 template <class P>
00241 struct select2nd : std::unary_function<P, typename P::second_type> {
00242 typename P::second_type& operator()(P& x) const {
00243 return x.second;
00244 }
00245 const typename P::second_type& operator()(const P& x) const {
00246 return x.second;
00247 }
00248 };
00249
00251 template <class OP1, class OP2>
00252 struct compose_1 : public std::unary_function<
00253 typename OP2::argument_type,
00254 typename OP1::result_type> {
00255 compose_1(const OP1& op1, const OP2& op2)
00256 : op1_(op1)
00257 , op2_(op2) {}
00258
00259 typename OP1::result_type operator()(const typename OP2::argument_type& x) const {
00260 return op1_(op2_(x));
00261 }
00262 protected:
00263 OP1 op1_;
00264 OP2 op2_;
00265 };
00266
00271 template <class OP1, class OP2>
00272 inline compose_1<OP1, OP2> compose1(const OP1& op1, const OP2& op2) {
00273 return compose_1<OP1, OP2>(op1, op2);
00274 }
00275
00277 template <class OP1, class OP2, class OP3>
00278 struct compose_2_1 : public std::unary_function<
00279 typename OP2::argument_type,
00280 typename OP1::result_type> {
00281 compose_2_1(const OP1& op1, const OP2& op2, const OP3& op3)
00282 : op1_(op1)
00283 , op2_(op2)
00284 , op3_(op3) {}
00285
00286 typename OP1::result_type operator()(const typename OP2::argument_type& x) const {
00287 return op1_(op2_(x), op3_(x));
00288 }
00289 protected:
00290 OP1 op1_;
00291 OP2 op2_;
00292 OP3 op3_;
00293 };
00294
00299 template <class OP1, class OP2, class OP3>
00300 inline compose_2_1<OP1, OP2,OP3> compose2(const OP1& op1, const OP2& op2, const OP3& op3) {
00301 return compose_2_1<OP1, OP2, OP3>(op1, op2, op3);
00302 }
00303
00304
00306 template <class OP1, class OP2, class OP3>
00307 struct compose_2_2 : public std::binary_function<
00308 typename OP2::argument_type,
00309 typename OP3::argument_type,
00310 typename OP1::result_type> {
00311 compose_2_2(const OP1& op1 = OP1(), const OP2& op2 = OP2(), const OP3& op3 = OP3())
00312 : op1_(op1)
00313 , op2_(op2)
00314 , op3_(op3) {}
00315
00316 typename OP1::result_type operator()(const typename OP2::argument_type& x, const typename OP3::argument_type& y) const {
00317 return op1_(op2_(x), op3_(y));
00318 }
00319 protected:
00320 OP1 op1_;
00321 OP2 op2_;
00322 OP3 op3_;
00323 };
00324
00329 template <class OP1, class OP2, class OP3>
00330 inline compose_2_2<OP1, OP2,OP3> compose22(const OP1& op1, const OP2& op2, const OP3& op3) {
00331 return compose_2_2<OP1, OP2, OP3>(op1, op2, op3);
00332 }
00333
00334 template <class T, class D = DeleteObject>
00335 class SingleOwnerPtr {
00336 public:
00337 SingleOwnerPtr() : ptr_(0) {}
00338 explicit SingleOwnerPtr(T* ptr) : ptr_( set_bit(uintp(ptr),0) ) {}
00339 ~SingleOwnerPtr() { *this = 0; }
00340 bool is_owner() const { return test_bit(ptr_, 0); }
00341 T* get() const { return (T*)clear_bit(ptr_, 0); }
00342 T& operator*() const { return *get(); }
00343 T* operator->() const { return get(); }
00344 SingleOwnerPtr& operator=(T* ptr) { reset(ptr); return *this; }
00345 void swap(SingleOwnerPtr& o) { std::swap(ptr_, o.ptr_); }
00346 T* release() { store_clear_bit(ptr_, 0); return get(); }
00347 T* acquire() { store_set_bit(ptr_, 0); return get(); }
00348 void reset(T* x) {
00349 if (x != get() && is_owner()) { D deleter; deleter(release()); }
00350 ptr_ = set_bit(uintp(x),0);
00351 }
00352 private:
00353 SingleOwnerPtr(const SingleOwnerPtr&);
00354 SingleOwnerPtr& operator=(const SingleOwnerPtr&);
00355 uintp ptr_;
00356 };
00357
00358 template <class T>
00359 struct Range {
00360 Range(T x, T y) : lo(x), hi(y) { if (x > y) { hi = x; lo = y; } }
00361 T clamp(T val) const {
00362 if (val < lo) return lo;
00363 if (val > hi) return hi;
00364 return val;
00365 }
00366 T lo;
00367 T hi;
00368 };
00370 }
00371
00372 #endif