misc_types.h
Go to the documentation of this file.
00001 // 
00002 // Copyright (c) 2006-2007, Benjamin Kaufmann
00003 // 
00004 // This file is part of Clasp. See http://www.cs.uni-potsdam.de/clasp/ 
00005 // 
00006 // Clasp is free software; you can redistribute it and/or modify
00007 // it under the terms of the GNU General Public License as published by
00008 // the Free Software Foundation; either version 2 of the License, or
00009 // (at your option) any later version.
00010 // 
00011 // Clasp is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 // GNU General Public License for more details.
00015 // 
00016 // You should have received a copy of the GNU General Public License
00017 // along with Clasp; if not, write to the Free Software
00018 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
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>    // std::pair
00026 #include <functional> // std::unary_function, std::binary_function
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; // one of Event::Subsystem - subsystem that produced the event
00042         uint32 verb   : 2; // one of Event::Verbosity - the verbosity level of this event
00043         uint32 op     : 8; // operation that triggered the event
00044         uint32 id     : 16;// type id of event
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& /* ev */) {}
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 // Computes n choose k.
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


clasp
Author(s): Benjamin Kaufmann
autogenerated on Thu Aug 27 2015 12:41:39