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, const IntPropLevels&,
00079 cxx14::index_sequence<I...>);
00080
00081 private:
00083 std::tuple<Args...> _args;
00084 };
00085
00087 template<typename... Args>
00088 class DomArgs<IntVar, Args...> {
00089 public:
00091 DomArgs(IntVar, Args...);
00092
00093 protected:
00095 template<std::size_t... I>
00096 void apply(Home, BoolVar, const IntPropLevels&,
00097 cxx14::index_sequence<I...>);
00098
00099 private:
00101 std::tuple<IntVar, Args...> _args;
00102 };
00103
00104
00105
00106
00107
00108 template<typename... Args>
00109 DomArgs<Args...>::DomArgs(Args... args)
00110 : _args(std::forward<Args>(args)...) {}
00111
00112 template<typename... Args>
00113 template<std::size_t... I>
00114 void
00115 DomArgs<Args...>::apply(Home home, BoolVar b, const IntPropLevels&,
00116 cxx14::index_sequence<I...>) {
00117 dom(home, std::get<I>(_args)..., b);
00118 }
00119
00120 template<typename... Args>
00121 DomArgs<IntVar, Args...>::DomArgs(IntVar x, Args... args)
00122 : _args (x, std::forward<Args>(args)...) {}
00123
00124 template<typename... Args>
00125 template<std::size_t... I>
00126 void
00127 DomArgs<IntVar, Args...>::apply(Home home, BoolVar b,
00128 const IntPropLevels&,
00129 cxx14::index_sequence<I...>) {
00130 dom(home, std::get<I>(_args)..., b);
00131 }
00132
00133
00135 template<typename... Args>
00136 class DomExpr : public DomArgs<Args...>, public BoolExpr::Misc
00137 {
00138 public:
00139 using DomArgs<Args...>::DomArgs;
00140
00142 virtual void post(Home, BoolVar b, bool neg,
00143 const IntPropLevels&) override;
00145 virtual ~DomExpr() = default;
00146 };
00147
00148 template<typename... Args>
00149 void
00150 DomExpr<Args...>::post(Home home, BoolVar b, bool neg,
00151 const IntPropLevels& ipls)
00152 {
00153 DomArgs<Args...>::apply(home, neg ? (!b).expr (home, ipls) : b, ipls,
00154 cxx14::index_sequence_for<Args...>{});
00155 }
00156 }
00157
00158
00159
00160
00161
00162
00163 BoolExpr
00164 dom(const IntVar& x, int n) {
00165 return BoolExpr(new DomExpr<IntVar, int>(x, n));
00166 }
00167
00168 BoolExpr
00169 dom(const IntVar& x, int l, int u) {
00170 return BoolExpr(new DomExpr<IntVar, int, int>(x, l, u));
00171 }
00172
00173 BoolExpr
00174 dom(const IntVar& x, const IntSet& s) {
00175 return BoolExpr(new DomExpr<IntVar, IntSet>(x, s));
00176 }
00177
00178 #ifdef GECODE_HAS_SET_VARS
00179 BoolExpr
00180 dom(const SetVar& x, SetRelType rt, int i) {
00181 return BoolExpr(new DomExpr<SetVar, SetRelType, int>(x, rt, i));
00182 }
00183
00184 BoolExpr
00185 dom(const SetVar& x, SetRelType rt, int i, int j) {
00186 return BoolExpr(new DomExpr<SetVar, SetRelType, int, int>(x, rt, i, j));
00187 }
00188
00189 BoolExpr
00190 dom(const SetVar& x, SetRelType rt, const IntSet& s) {
00191 return BoolExpr(new DomExpr<SetVar, SetRelType, IntSet>(x, rt, s));
00192 }
00193 #endif
00194
00195 #ifdef GECODE_HAS_FLOAT_VARS
00196 BoolExpr
00197 dom(const FloatVar& x, const FloatVal& n) {
00198 return BoolExpr(new DomExpr<FloatVar, FloatVal>(x, n));
00199 }
00200
00201 BoolExpr
00202 dom(const FloatVar& x, FloatNum l, FloatNum u) {
00203 return BoolExpr(new DomExpr<FloatVar, FloatNum, FloatNum>(x, l, u));
00204 }
00205 #endif
00206 }
00207
00208