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 #include <gecode/minimodel.hh>
00035
00036 #include <cstddef>
00037 #include <tuple>
00038 #include <utility>
00039
00041 namespace { namespace cxx14 {
00042
00043 namespace detail {
00044
00045 template<std::size_t...>
00046 struct sequence {};
00047
00048 template<std::size_t N, std::size_t... I>
00049 struct make_sequence : make_sequence<N - 1, N - 1, I...> {};
00050
00051 template<std::size_t... I>
00052 struct make_sequence<0, I...> {
00053 using type = sequence<I...>;
00054 };
00055 }
00056
00057 template<std::size_t... I>
00058 using index_sequence = detail::sequence<I...>;
00059
00060 template<typename... Ts>
00061 using index_sequence_for = typename detail::make_sequence<sizeof...(Ts)>::type;
00062 }}
00063
00064
00065 namespace Gecode {
00066
00067 namespace {
00069 template<typename... Args>
00070 class DomArgs {
00071 public:
00073 DomArgs(Args...);
00074
00075 protected:
00077 template<std::size_t... I>
00078 void apply(Home, BoolVar, IntPropLevel, cxx14::index_sequence<I...>);
00079
00080 private:
00082 std::tuple<Args...> _args;
00083 };
00084
00086 template<typename... Args>
00087 class DomArgs<IntVar, Args...> {
00088 public:
00090 DomArgs(IntVar, Args...);
00091
00092 protected:
00094 template<std::size_t... I>
00095 void apply(Home, BoolVar, IntPropLevel, cxx14::index_sequence<I...>);
00096
00097 private:
00099 std::tuple<IntVar, Args...> _args;
00100 };
00101
00102
00103
00104
00105
00106 template<typename... Args>
00107 DomArgs<Args...>::DomArgs(Args... args)
00108 : _args(std::forward<Args>(args)...) {}
00109
00110 template<typename... Args>
00111 template<std::size_t... I>
00112 void
00113 DomArgs<Args...>::apply(Home home, BoolVar b, IntPropLevel,
00114 cxx14::index_sequence<I...>) {
00115 dom(home, std::get<I>(_args)..., b);
00116 }
00117
00118 template<typename... Args>
00119 DomArgs<IntVar, Args...>::DomArgs(IntVar x, Args... args)
00120 : _args (x, std::forward<Args>(args)...) {}
00121
00122 template<typename... Args>
00123 template<std::size_t... I>
00124 void
00125 DomArgs<IntVar, Args...>::apply(Home home, BoolVar b, IntPropLevel ipl,
00126 cxx14::index_sequence<I...>) {
00127 dom(home, std::get<I>(_args)..., b, ipl);
00128 }
00129
00130
00132 template<typename... Args>
00133 class DomExpr : public DomArgs<Args...>, public BoolExpr::Misc
00134 {
00135 public:
00136 using DomArgs<Args...>::DomArgs;
00137
00139 virtual void post(Home, BoolVar b, bool neg, IntPropLevel) override;
00141 virtual ~DomExpr() = default;
00142 };
00143
00144 template<typename... Args>
00145 void
00146 DomExpr<Args...>::post(Home home, BoolVar b, bool neg, IntPropLevel ipl)
00147 {
00148 DomArgs<Args...>::apply(home, neg ? (!b).expr (home, ipl) : b, ipl,
00149 cxx14::index_sequence_for<Args...>{});
00150 }
00151 }
00152
00153
00154
00155
00156
00157
00158 BoolExpr
00159 dom(const IntVar& x, int n) {
00160 return BoolExpr(new DomExpr<IntVar, int>(x, n));
00161 }
00162
00163 BoolExpr
00164 dom(const IntVar& x, int l, int u) {
00165 return BoolExpr(new DomExpr<IntVar, int, int>(x, l, u));
00166 }
00167
00168 BoolExpr
00169 dom(const IntVar& x, const IntSet& s) {
00170 return BoolExpr(new DomExpr<IntVar, IntSet>(x, s));
00171 }
00172
00173 #ifdef GECODE_HAS_SET_VARS
00174 BoolExpr
00175 dom(const SetVar& x, SetRelType rt, int i) {
00176 return BoolExpr(new DomExpr<SetVar, SetRelType, int>(x, rt, i));
00177 }
00178
00179 BoolExpr
00180 dom(const SetVar& x, SetRelType rt, int i, int j) {
00181 return BoolExpr(new DomExpr<SetVar, SetRelType, int, int>(x, rt, i, j));
00182 }
00183
00184 BoolExpr
00185 dom(const SetVar& x, SetRelType rt, const IntSet& s) {
00186 return BoolExpr(new DomExpr<SetVar, SetRelType, IntSet>(x, rt, s));
00187 }
00188 #endif
00189
00190 #ifdef GECODE_HAS_FLOAT_VARS
00191 BoolExpr
00192 dom(const FloatVar& x, const FloatVal& n) {
00193 return BoolExpr(new DomExpr<FloatVar, FloatVal>(x, n));
00194 }
00195
00196 BoolExpr
00197 dom(const FloatVar& x, FloatNum l, FloatNum u) {
00198 return BoolExpr(new DomExpr<FloatVar, FloatNum, FloatNum>(x, l, u));
00199 }
00200 #endif
00201 }
00202
00203