31 template <
typename T,
typename PVT,
class Context,
class C,
typename... CalculatorArgs>
32 class anchor :
public i_calculating_anchor<T, PVT, CalculatorArgs...>
34 typedef i_calculating_anchor<T, PVT, CalculatorArgs...> base_type;
36 using typename base_type::abstract_type;
37 using typename base_type::value_type;
38 using typename base_type::property_value_type;
39 using typename base_type::constraint;
42 typedef T(
C::* calculator_function_type)(CalculatorArgs...) const;
43 typedef std::pair<constraint, std::shared_ptr<i_anchor>> constraint_entry_t;
44 typedef std::vector<constraint_entry_t> constraint_entries_t;
47 iOwnerDestroying{ aOwner.as_object() }, iOwner { aOwner }, iProperty{ aProperty }, iCalculating{ false }
52 iOwnerDestroying{ aOwner.as_object() }, iOwner{ aOwner }, iProperty{ aProperty }, iCalculatorOverride{ aCalculatorOverride }, iCalculating{ false }
58 if (!iOwnerDestroying)
82 bool active() const noexcept
override
84 return !iConstraints.empty();
88 return iCalculatorOverride != std::nullopt;
98 aRhs.constrain(*
this, aLhsFunction);
102 switch (aOtherFunction)
105 add_constraint(constraint::identity,
static_cast<abstract_type&
>(aOther));
108 add_constraint(constraint::identity_x,
static_cast<abstract_type&
>(aOther));
111 add_constraint(constraint::identity_y,
static_cast<abstract_type&
>(aOther));
114 add_constraint(constraint::equal,
static_cast<abstract_type&
>(aOther));
117 add_constraint(constraint::equal_x,
static_cast<abstract_type&
>(aOther));
120 add_constraint(constraint::equal_y,
static_cast<abstract_type&
>(aOther));
123 add_constraint(constraint::min,
static_cast<abstract_type&
>(aOther));
126 add_constraint(constraint::min_x,
static_cast<abstract_type&
>(aOther));
129 add_constraint(constraint::min_y,
static_cast<abstract_type&
>(aOther));
132 add_constraint(constraint::max,
static_cast<abstract_type&
>(aOther));
135 add_constraint(constraint::max_x,
static_cast<abstract_type&
>(aOther));
138 add_constraint(constraint::max_y,
static_cast<abstract_type&
>(aOther));
153 return property().
get<property_value_type>() != std::nullopt;
162 throw anchor_property_has_no_value();
166 return const_cast<value_type&
>(to_const(*this).property_value());
168 void add_constraint(constraint
const& aConstraint, abstract_type& aOtherAnchor)
override
170 add_constraint(aConstraint, std::shared_ptr<abstract_type>{ std::shared_ptr<abstract_type>{}, &aOtherAnchor });
172 void add_constraint(constraint
const& aConstraint, std::shared_ptr<abstract_type> aOtherAnchor)
override
174 iConstraints.push_back(constraint_entry_t{ aConstraint, aOtherAnchor });
179 for (
auto const& c : iConstraints)
181 auto const& otherAnchor =
static_cast<abstract_type&
>(*c.second);
182 result = c.first(result, otherAnchor.calculate(aArgs...));
186 value_type
calculate(
const CalculatorArgs&... aArgs)
const override
190 return (
static_cast<Context&
>(iOwner).**iCalculatorOverride)(aArgs...);
197 destroying_flag iOwnerDestroying;
200 constraint_entries_t iConstraints;
201 std::optional<calculator_function_type> iCalculatorOverride;
202 mutable bool iCalculating;
207 template <
template<
typename,
typename,
typename,
typename...>
class Anchor,
class Ctx,
typename PVT,
typename Callable>
208 struct anchor_callable_function_cracker;
209 template <
template<
typename,
typename,
typename,
typename...>
class Anchor,
class Ctx,
typename PVT,
typename R,
typename C,
typename... Args>
210 struct anchor_callable_function_cracker<Anchor, Ctx, PVT, R(
C::*)(Args...) const>
212 typedef Anchor<R, PVT, std::add_const_t<Ctx>,
C, Args...> type;
213 typedef R(
C::* callable_type)(Args...) const;
214 typedef PVT property_value_type;
215 typedef R value_type;
216 typedef C class_type;
218 template <
template<
typename,
typename,
typename,
typename...>
class Anchor,
class Ctx,
typename PVT,
typename R,
typename C,
typename... Args>
219 struct anchor_callable_function_cracker<Anchor, Ctx, PVT, R(
C::*)(Args...)>
221 typedef Anchor<R, PVT, Ctx,
C, Args...> type;
222 typedef R(
C::* callable_type)(Args...);
223 typedef PVT property_value_type;
224 typedef R value_type;
225 typedef C class_type;
229 template <
typename Context,
typename PVT,
typename Callable>
230 using anchor_t =
typename detail::anchor_callable_function_cracker<anchor, Context, PVT, Callable>::type;
232 #define define_anchor( name ) neogfx::anchor_t<property_context_type, typename decltype(name)::value_type, typename decltype(name)::calculator_function_type> Anchor_##name = { *this, name };
233 #define define_anchor_ex( name, calculator_override ) neogfx::anchor_t<property_context_type, typename decltype(name)::value_type, typename decltype(name)::calculator_function_type> Anchor_##name = { *this, name, &property_context_type::##calculator_override };
bool active() const noexcept override
const i_property & property() const override
anchor(i_anchorable &aOwner, i_property &aProperty, calculator_function_type aCalculatorOverride)
i_property & property() override
void constrain(i_anchor &aRhs, anchor_constraint_function aLhsFunction, anchor_constraint_function aRhsFunction) override
value_type const & property_value() const override
void add_constraint(constraint const &aConstraint, abstract_type &aOtherAnchor) override
bool property_set() const
value_type evaluate_constraints(CalculatorArgs const &... aArgs) const override
const i_string & name() const override
void constrain(i_anchor &aOther, anchor_constraint_function aOtherFunction) override
anchor(i_anchorable &aOwner, i_property &aProperty)
i_anchorable & owner() const override
value_type & property_value() override
void add_constraint(constraint const &aConstraint, std::shared_ptr< abstract_type > aOtherAnchor) override
bool calculator_overriden() const noexcept override
bool calculating() const noexcept override
value_type calculate(const CalculatorArgs &... aArgs) const override
virtual const anchor_map_type & anchors() const =0
virtual const i_string & name() const =0
auto calculate(Args &&... aArgs) const
iterator erase(const abstract_iterator &aPosition)
const_iterator end() const
const_iterator find(const abstract_key_type &aKey) const
anchor_constraint_function
typename detail::anchor_callable_function_cracker< anchor, Context, PVT, Callable >::type anchor_t
ref_ptr< ConcreteType > make_ref(Args &&... args)