Generated on Thu Apr 11 13:59:14 2019 for Gecode by doxygen 1.6.3

function.cpp

Go to the documentation of this file.
00001 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
00002 /*
00003  *  Main authors:
00004  *     Christian Schulte <schulte@gecode.org>
00005  *     Mikael Lagerkvist <lagerkvist@gecode.org>
00006  *
00007  *  Copyright:
00008  *     Christian Schulte, 2008
00009  *     Mikael Lagerkvist, 2008
00010  *
00011  *  This file is part of Gecode, the generic constraint
00012  *  development environment:
00013  *     http://www.gecode.org
00014  *
00015  *  Permission is hereby granted, free of charge, to any person obtaining
00016  *  a copy of this software and associated documentation files (the
00017  *  "Software"), to deal in the Software without restriction, including
00018  *  without limitation the rights to use, copy, modify, merge, publish,
00019  *  distribute, sublicense, and/or sell copies of the Software, and to
00020  *  permit persons to whom the Software is furnished to do so, subject to
00021  *  the following conditions:
00022  *
00023  *  The above copyright notice and this permission notice shall be
00024  *  included in all copies or substantial portions of the Software.
00025  *
00026  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00027  *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00028  *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00029  *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
00030  *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
00031  *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
00032  *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
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 // STATISTICS: kernel-branch