function.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include <gecode/kernel.hh>
00037
00038 namespace Gecode { namespace Kernel {
00039
00041 class FunctionBranch : public Brancher {
00042 protected:
00044 class Description : public Choice {
00045 public:
00047 Description(const Brancher& b, unsigned int a);
00049 virtual void archive(Archive& e) const;
00050 };
00052 SharedData<std::function<void(Space& home)>> f;
00054 bool done;
00056 FunctionBranch(Home home, std::function<void(Space& home)> f0);
00058 FunctionBranch(Space& home, FunctionBranch& b);
00059 public:
00061 virtual bool status(const Space& home) const;
00063 virtual const Choice* choice(Space& home);
00065 virtual const Choice* choice(const Space& home, Archive& a);
00067 virtual ExecStatus commit(Space& home, const Choice& ch, unsigned int a);
00069 virtual void print(const Space&, const Choice&, unsigned int,
00070 std::ostream& o) const;
00072 virtual Actor* copy(Space& home);
00074 static void post(Home home, std::function<void(Space& home)> f);
00076 virtual size_t dispose(Space& home);
00077 };
00078
00079 forceinline
00080 FunctionBranch::Description::Description(const Brancher& b, unsigned int a)
00081 : Choice(b,a) {}
00082 void
00083 FunctionBranch::Description::archive(Archive& e) const {
00084 Choice::archive(e);
00085 }
00086
00087 forceinline
00088 FunctionBranch::FunctionBranch(Home home,
00089 std::function<void(Space& home)> f0)
00090 : Brancher(home), f(f0), done(false) {
00091 if (!f())
00092 throw InvalidFunction("FunctionBranch::FunctionBranch");
00093 home.notice(*this,AP_DISPOSE);
00094 }
00095 forceinline
00096 FunctionBranch::FunctionBranch(Space& home, FunctionBranch& b)
00097 : Brancher(home,b), f(b.f), done(b.done) {
00098 }
00099 bool
00100 FunctionBranch::status(const Space&) const {
00101 return !done;
00102 }
00103 const Choice*
00104 FunctionBranch::choice(Space&) {
00105 assert(!done);
00106 return new Description(*this,1);
00107 }
00108 const Choice*
00109 FunctionBranch::choice(const Space&, Archive&) {
00110 return new Description(*this,1);
00111 }
00112 ExecStatus
00113 FunctionBranch::commit(Space& home, const Choice&, unsigned int) {
00114 done = true;
00115 GECODE_VALID_FUNCTION(f());
00116 f()(home);
00117 return home.failed() ? ES_FAILED : ES_OK;
00118 }
00119 void
00120 FunctionBranch::print(const Space&, const Choice&, unsigned int,
00121 std::ostream& o) const {
00122 o << "FunctionBranch()";
00123 }
00124 Actor*
00125 FunctionBranch::copy(Space& home) {
00126 return new (home) FunctionBranch(home,*this);
00127 }
00128 forceinline void
00129 FunctionBranch::post(Home home, std::function<void(Space& home)> f) {
00130 if (!f)
00131 throw InvalidFunction("FunctionBranch::post");
00132 (void) new (home) FunctionBranch(home,f);
00133 }
00134 size_t
00135 FunctionBranch::dispose(Space& home) {
00136 home.ignore(*this,AP_DISPOSE);
00137 f.~SharedData<std::function<void(Space& home)>>();
00138 (void) Brancher::dispose(home);
00139 return sizeof(*this);
00140 }
00141
00142 }}
00143
00144 namespace Gecode {
00145
00146 void
00147 branch(Home home, std::function<void(Space& home)> f) {
00148 Kernel::FunctionBranch::post(home,f);
00149 }
00150
00151 }
00152
00153