2#ifndef TTG_CONSTRAINT_H
3#define TTG_CONSTRAINT_H
13#ifdef TTG_USE_BUNDLED_BOOST_CALLABLE_TRAITS
21 template<
typename Key>
24 using listener_t = std::function<void(
const ttg::span<key_type>&)>;
30 : m_listeners(
std::move(cb.m_listeners))
34 : m_listeners(cb.m_listeners)
38 m_listeners = std::move(cb.m_listeners);
41 m_listeners = cb.m_listeners;
48 m_listeners.insert_or_assign(tt, std::move(l));
52 auto& release = m_listeners[tt];
59 return std::lock_guard{m_mtx};
63 std::map<ttg::TTBase*, listener_t> m_listeners;
67 template<
typename Key,
68 typename Ordinal = std::size_t,
69 typename Compare = std::less<Ordinal>,
79 static_assert((!Compare{}(Ordinal{}, Ordinal{})),
"Comparator must provide strict ordering.");
83 std::map<ttg::TTBase*, std::vector<key_type>>
m_keys;
94 m_keys.insert(std::make_pair(tt, std::vector<key_type>{key}));
96 it->second.push_back(key);
114 m_active.fetch_add(1, std::memory_order_relaxed);
125 m_active.fetch_add(1, std::memory_order_relaxed);
141 it->second.add_key(key, tt);
148 auto active =
m_active.fetch_sub(1, std::memory_order_relaxed) - 1;
171 elem = std::move(it->second);
175 for (
auto& seq : elem.
m_keys) {
177 this->
m_active.fetch_add(seq.second.size(), std::memory_order_relaxed);
178 this->
notify_listener(ttg::span<key_type>(seq.second.data(), seq.second.size()), seq.first);
190 if (!force_check &&
eligible(ord)) {
194 std::vector<sequence_elem_t> seqs;
203 seqs.push_back(std::move(it->second));
207 for (
auto& elem : seqs) {
208 for (
auto& e : elem.m_keys) {
210 this->
notify_listener(ttg::span<key_type>(e.second.data(), e.second.size()), e.first);
225 template<
typename Mapper_>
226 requires(std::is_invocable_v<Mapper_, Key>)
229 ,
m_map(std::forward<Mapper_>(map))
246 template<
typename Key_ = key_type,
typename Mapper_ = Mapper>
253 template<
typename Key_ = key_type,
typename Mapper_ = Mapper>
259 template<
typename Key_ = key_type,
typename Mapper_ = Mapper>
265 template<
typename Key_ = key_type,
typename Mapper_ = Mapper>
271 template<
typename Key_ = key_type,
typename Mapper_ = Mapper>
277 template<
typename Key_ = key_type,
typename Mapper_ = Mapper>
283 template<
typename Key_ = key_type,
typename Mapper_ = Mapper>
289 template<
typename Key_ = key_type,
typename Mapper_ = Mapper>
317 if (ord == std::numeric_limits<ordinal_type>::min() &&
318 this->
m_sequence.begin() != this->m_sequence.end()) {
345 std::map<ordinal_type, sequence_elem_t, compare_t>
m_sequence;
347 [[no_unique_address]]
349 [[no_unique_address]]
358 template<
typename Mapper,
typename = std::enable_if_t<std::is_invocable_v<Mapper, std::decay_t<std::tuple_element_t<0, boost::callable_traits::args_t<Mapper>>>>>>
361 std::decay_t<std::tuple_element_t<0, boost::callable_traits::args_t<Mapper>>>,
362 std::decay_t<boost::callable_traits::return_type_t<Mapper>>,
363 std::less<std::decay_t<boost::callable_traits::return_type_t<Mapper>>>,
364 std::enable_if_t<std::is_invocable_v<Mapper, std::decay_t<std::tuple_element_t<0, boost::callable_traits::args_t<Mapper>>>>, Mapper>
367 template<
typename Mapper,
typename = std::enable_if_t<std::is_invocable_v<Mapper, std::decay_t<std::tuple_element_t<0, boost::callable_traits::args_t<Mapper>>>>>>
370 std::decay_t<std::tuple_element_t<0, boost::callable_traits::args_t<Mapper>>>,
371 std::decay_t<boost::callable_traits::return_type_t<Mapper>>,
372 std::less<std::decay_t<boost::callable_traits::return_type_t<Mapper>>>,
373 std::enable_if_t<std::is_invocable_v<Mapper, std::decay_t<std::tuple_element_t<0, boost::callable_traits::args_t<Mapper>>>>, Mapper>
376 template<
typename Key,
typename Ordinal,
typename Compare,
typename Mapper>
380 template<
typename Key,
typename Ordinal,
typename Compare,
typename Mapper>
398 template<
template<
typename...>
typename Constraint,
typename... Args>
400 return std::make_shared<decltype(Constraint(std::forward<Args>(args)...))>(std::forward<Args>(args)...);
407 template<
typename Constraint,
typename... Args>
409 return std::make_shared<Constraint>(std::forward<Args>(args)...);
A base class for all template tasks.
A complete version of void.
top-level TTG namespace contains runtime-neutral functionality
auto make_shared_constraint(Args &&... args)
void notify_listener(const ttg::span< key_type > &keys, ttg::TTBase *tt)
ConstraintBase(ConstraintBase &&cb)
virtual ~ConstraintBase()=default
ConstraintBase & operator=(const ConstraintBase &cb)
ConstraintBase(const ConstraintBase &cb)
std::function< void(const ttg::span< key_type > &)> listener_t
void add_listener(listener_t l, ttg::TTBase *tt)
ConstraintBase & operator=(ConstraintBase &&cb)
std::map< ttg::TTBase *, std::vector< key_type > > m_keys
sequence_elem_t(sequence_elem_t &&)=default
sequence_elem_t(const sequence_elem_t &)=default
sequence_elem_t()=default
void add_key(const key_type &key, ttg::TTBase *tt)
sequence_elem_t & operator=(const sequence_elem_t &)=default
sequence_elem_t & operator=(sequence_elem_t &&)=default
std::enable_if_t<!ttg::meta::is_void_v< Key_ > &&!ttg::meta::is_void_v< Mapper_ > > complete(const key_type &key, ttg::TTBase *tt)
SequencedKeysConstraint(bool auto_release=false)
std::enable_if_t<!ttg::meta::is_void_v< Key_ > &&ttg::meta::is_void_v< Mapper_ > > complete(Ordinal ord, ttg::TTBase *tt)
std::enable_if_t< ttg::meta::is_void_v< Key_ > &&!ttg::meta::is_void_v< Mapper_ >, bool > check(ttg::TTBase *tt)
SequencedKeysConstraint & operator=(SequencedKeysConstraint &&skc)=default
bool check_key_impl(const key_type &key, Ordinal ord, ttg::TTBase *tt)
std::enable_if_t< ttg::meta::is_void_v< Key_ > &&ttg::meta::is_void_v< Mapper_ >, bool > check(ordinal_type ord, ttg::TTBase *tt)
SequencedKeysConstraint & operator=(const SequencedKeysConstraint &skc)=default
ConstraintBase< Key > base_t
std::enable_if_t<!ttg::meta::is_void_v< Key_ > &&ttg::meta::is_void_v< Mapper_ >, bool > check(const key_type &key, Ordinal ord, ttg::TTBase *tt)
std::atomic< std::size_t > m_active
bool comp_equal(const Ordinal &a, const Ordinal &b) const
virtual ~SequencedKeysConstraint()=default
void release(ordinal_type ord=0)
std::conditional_t< ttg::meta::is_void_v< Key >, ttg::Void, Key > key_type
std::map< ordinal_type, sequence_elem_t, compare_t > m_sequence
std::enable_if_t<!ttg::meta::is_void_v< Key_ > &&!ttg::meta::is_void_v< Mapper_ >, bool > check(const key_type &key, ttg::TTBase *tt)
void release_next(ordinal_type ord, bool force_check=false)
SequencedKeysConstraint(const SequencedKeysConstraint &skc)=default
std::enable_if_t<!ttg::meta::is_void_v< Key_ > &&ttg::meta::is_void_v< Mapper_ > > complete(const key_type &key, Ordinal ord, ttg::TTBase *tt)
std::function< Ordinal(const key_type &)> keymap_t
std::enable_if_t<!ttg::meta::is_void_v< Key_ > &&!ttg::meta::is_void_v< Mapper_ > > complete(ttg::TTBase *tt)
SequencedKeysConstraint(Mapper_ &&map, bool auto_release=false)
bool eligible(const Ordinal &ord) const
SequencedKeysConstraint(SequencedKeysConstraint &&skc)=default