Arcane  4.1.12.0
Developer documentation
Loading...
Searching...
No Matches
AnyItemFamily.h
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2026 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/* AnyItemFamily.h (C) 2000-2025 */
9/* */
10/* Family of items of arbitrary types. */
11/*---------------------------------------------------------------------------*/
12#ifndef ARCANE_CORE_ANYITEM_ANYITEMFAMILY_H
13#define ARCANE_CORE_ANYITEM_ANYITEMFAMILY_H
14/*---------------------------------------------------------------------------*/
15/*---------------------------------------------------------------------------*/
16
17#include "arcane/utils/SharedPtr.h"
18
19#include <set>
20
21/*---------------------------------------------------------------------------*/
22/*---------------------------------------------------------------------------*/
23
24#include "arcane/utils/FatalErrorException.h"
25#include "arcane/core/anyitem/AnyItemGlobal.h"
26#include "arcane/core/anyitem/AnyItemPrivate.h"
27#include "arcane/core/anyitem/AnyItemGroup.h"
28#include "arcane/core/anyitem/AnyItemFamilyObserver.h"
29#include "arcane/core/ItemGroupObserver.h"
30
31/*---------------------------------------------------------------------------*/
32/*---------------------------------------------------------------------------*/
33
34namespace Arcane::AnyItem
35{
36
37/*---------------------------------------------------------------------------*/
38/*---------------------------------------------------------------------------*/
39
44class FamilyInternal
45{
46 private:
47
48 typedef std::set<IFamilyObserver*> FamilyObservers;
49
50 public:
51
52 FamilyInternal()
54 {}
55 ~FamilyInternal()
56 {
57 clear();
58 }
59
60 public:
61
63 FamilyInternal& operator<<(GroupBuilder builder)
64 {
65 ItemGroup group = builder.group();
66 const Integer size = m_groups.size();
67
68 if (m_groups.findGroupInfo(group.internal()) != NULL)
69 throw FatalErrorException(String::format("Group '{0}' already registered", group.name()));
70
71 m_groups.resize(size + 1);
73 info.group = group.internal();
74 info.group_index = size;
75 info.local_id_offset = m_max_local_id;
76 m_max_local_id += group.size();
77 info.is_partial = builder.isPartial();
78 info.group->attachObserver(this, newItemGroupObserverT(this, &FamilyInternal::_notifyGroupHasChanged));
79 // std::cout << "Attach " << this << " observer on group " << group.name() << "\n";
80
81 // Notify observers
82 _notifyFamilyIsIncreased();
83 return *this;
84 }
85
87 inline bool contains(const ItemGroup& group) const
88 {
89 return (m_groups.findGroupInfo(group.internal()) != NULL);
90 }
91
93 inline bool isPartial(const ItemGroup& group) const
94 {
95 const Private::GroupIndexInfo* info = m_groups.findGroupInfo(group.internal());
96 if (info == NULL)
97 throw Arcane::FatalErrorException(Arcane::String::format("Group '{0}' not registered", group.name()));
98 return info->is_partial;
99 }
100
102 // This group does not need to observe the family because it shares the data
103 inline Group allItems() const
104 {
105 return m_groups;
106 }
107
109 inline Integer groupIndex(const ItemGroup& group) const
110 {
111 const Private::GroupIndexInfo* info = m_groups.findGroupInfo(group.internal());
112 if (info == NULL)
113 throw FatalErrorException(String::format("Group '{0}' not registered", group.name()));
114 return info->group_index;
115 }
116
118 inline Integer firstLocalId(const ItemGroup& group) const
119 {
120 const Private::GroupIndexInfo* info = m_groups.findGroupInfo(group.internal());
121 if (!info)
122 ARCANE_FATAL("Group '{0}' not registered", group.name());
123 return info->local_id_offset;
124 }
125
127 template <typename AnyItemT>
128 Item item(const AnyItemT& any_item) const
129 {
130 // NOTE GG: the value of group.itemInfoListView() does not change during
131 // calculation, so it is possible to keep it as a class field.
132 const Integer group_index = any_item.groupIndex();
133 const Private::GroupIndexInfo& info = m_groups[group_index];
134 const ItemGroupImpl& group = *(info.group);
135 Integer index_in_group = any_item.localId() - info.local_id_offset;
136 Item item = group.itemInfoListView()[group.itemsLocalId()[index_in_group]];
137 // ARCANE_ASSERT((!info.is_partial || (item->localId() == any_item.varIndex())),("Inconsistent concrete item"));
138 // ARCANE_ASSERT((item->isOwn() == any_item.m_is_own),("Inconsistent concrete item isOwn"));
139 return item;
140 }
141
143 inline Integer groupSize() const
144 {
145 return m_groups.size();
146 }
147
149
150 inline Integer maxLocalId() const
151 {
152 return m_max_local_id;
153 }
154
157 {
158 return ItemGroup(m_groups[i].group);
159 }
160
162 void clear()
163 {
164 for (Integer igrp = 0; igrp < m_groups.size(); ++igrp) {
165 m_groups[igrp].group->detachObserver(this);
166 // std::cout << "Detach " << this << " observer on group " << m_groups[igrp].group->name() << "\n";
167 }
168 // Clear
169 m_groups.clear();
170 m_max_local_id = 0;
171 // Notify observers
172 _notifyFamilyIsInvalidate();
173 }
174
176 void registerObserver(IFamilyObserver& observer) const
177 {
178 FamilyObservers::const_iterator it = m_observers.find(&observer);
179 if (it != m_observers.end())
180 throw FatalErrorException("FamilyObserver already registered");
181 m_observers.insert(&observer);
182 }
183
185 void removeObserver(IFamilyObserver& observer) const
186 {
187 FamilyObservers::const_iterator it = m_observers.find(&observer);
188 if (it == m_observers.end())
189 throw FatalErrorException("FamilyObserver not registered");
190 m_observers.erase(it);
191 }
192
193 public:
194
195 const Private::GroupIndexInfo* findGroupInfo(ItemGroup agroup)
196 {
197 return m_groups.findGroupInfo(agroup.internal());
198 }
199
200 private:
201
202 void _notifyFamilyIsInvalidate()
203 {
204 for (FamilyObservers::iterator it = m_observers.begin(); it != m_observers.end(); ++it)
205 (*it)->notifyFamilyIsInvalidate();
206 }
207
208 void _notifyFamilyIsIncreased()
209 {
210 for (FamilyObservers::iterator it = m_observers.begin(); it != m_observers.end(); ++it)
211 (*it)->notifyFamilyIsIncreased();
212 }
213
214 void _notifyGroupHasChanged()
215 {
216 throw FatalErrorException(A_FUNCINFO, "Group changes while registered in AnyItem::Family");
217 }
218
219 private:
220
223
226
228 mutable FamilyObservers m_observers;
229};
230
231/*---------------------------------------------------------------------------*/
232/*---------------------------------------------------------------------------*/
233
239class Family
240{
241 public:
242
243 Family()
245 {}
246 Family(const Family& f)
248 {}
249 ~Family() {}
250
251 public:
252
254 bool operator==(const Family& f) const { return m_internal == f.m_internal; }
255 bool operator!=(const Family& f) const { return !operator==(f); }
256
257 Family& operator=(const Family& f)
258 {
259 m_internal = f.m_internal;
260 return *this;
261 }
262
264 Family& operator<<(GroupBuilder builder)
265 {
266 *m_internal << builder;
267 return *this;
268 }
269
271 inline bool contains(const ItemGroup& group) const
272 {
273 return m_internal->contains(group);
274 }
275
277 inline bool isPartial(const ItemGroup& group) const
278 {
279 return m_internal->isPartial(group);
280 }
281
284 {
285 return m_internal->allItems();
286 }
287
289 inline Integer groupIndex(const ItemGroup& group) const
290 {
291 return m_internal->groupIndex(group);
292 }
293
295 inline Integer firstLocalId(const ItemGroup& group) const
296 {
297 return m_internal->firstLocalId(group);
298 }
299
301 template <typename AnyItemT>
302 Item item(const AnyItemT& any_item) const
303 {
304 return m_internal->item(any_item);
305 }
306
308 inline Integer groupSize() const
309 {
310 return m_internal->groupSize();
311 }
312
314
315 inline Integer maxLocalId() const
316 {
317 return m_internal->maxLocalId();
318 }
319
322 {
323 return m_internal->group(i);
324 }
325
327 void clear()
328 {
329 m_internal->clear();
330 }
331
333 void registerObserver(IFamilyObserver& observer) const
334 {
335 m_internal->registerObserver(observer);
336 }
337
339 void removeObserver(IFamilyObserver& observer) const
340 {
341 m_internal->removeObserver(observer);
342 }
343
344 FamilyInternal* internal() const
345 {
346 return m_internal.get();
347 }
348
349 private:
350
353};
354
355/*---------------------------------------------------------------------------*/
356/*---------------------------------------------------------------------------*/
357
358} // namespace Arcane::AnyItem
359
360/*---------------------------------------------------------------------------*/
361/*---------------------------------------------------------------------------*/
362
363#endif
#define ARCANE_FATAL(...)
Macro throwing a FatalErrorException.
AnyItem internal family Aggregation of groups to describe variables / partial variables.
Private::GroupIndexMapping m_groups
Container of groups.
bool contains(const ItemGroup &group) const
Returns true if the family contains the group.
Integer groupSize() const
Size of the family, i.e., number of groups.
Integer m_max_local_id
Maximum identifier (equivalent to the size of the family).
ItemGroup group(Integer i) const
Accessor for the i-th group of the family.
void removeObserver(IFamilyObserver &observer) const
Remove an observer.
Item item(const AnyItemT &any_item) const
Returns the concrete item associated with this AnyItem.
void registerObserver(IFamilyObserver &observer) const
Register an observer.
FamilyObservers m_observers
So that objects built on the family cannot modify it.
Integer firstLocalId(const ItemGroup &group) const
Position in the family of the first localId of this group.
void clear()
Clear the family.
Group allItems() const
Group of all items.
bool isPartial(const ItemGroup &group) const
Returns true if the group is associated with a partial variable.
Integer maxLocalId() const
Number of items in this family.
Integer groupIndex(const ItemGroup &group) const
Position of the group in the family.
FamilyInternal & operator<<(GroupBuilder builder)
Add a group to the family.
AnyItem family (flyweight pattern) Aggregation of groups to describe variables / partial variables Co...
ItemGroup group(Integer i) const
Accessor for the i-th group of the family.
Integer maxLocalId() const
Number of items in this family.
Integer firstLocalId(const ItemGroup &group) const
Position in the family of the first localId of this group.
bool operator==(const Family &f) const
Comparisons.
Item item(const AnyItemT &any_item) const
Returns the concrete item associated with this AnyItem.
SharedPtrT< FamilyInternal > m_internal
Internal family.
bool isPartial(const ItemGroup &group) const
Returns true if the group is associated with a partial variable.
void removeObserver(IFamilyObserver &observer) const
Remove an observer.
Integer groupSize() const
Size of the family, i.e., number of groups.
Group allItems()
Group of all items.
void clear()
Clear the family.
Family & operator<<(GroupBuilder builder)
Add a group to the family.
bool contains(const ItemGroup &group) const
Returns true if the family contains the group.
void registerObserver(IFamilyObserver &observer) const
Register an observer.
Integer groupIndex(const ItemGroup &group) const
Position of the group in the family.
Tool for building a group.
AnyItem Group Aggregation of Arcane group + information {partial or not} for variables Construction w...
AnyItem family observer interface.
Brief: Implementation of a mesh entity group.
void attachObserver(const void *ref, IItemGroupObserver *obs)
Attaches an observer.
Mesh entity group.
Definition ItemGroup.h:51
ItemGroupImpl * internal() const
Returns the group implementation.
Definition ItemGroup.h:125
Base class for a mesh element.
Definition Item.h:84
Int32 Integer
Type representing an integer.
IItemGroupObserver * newItemGroupObserverT(T *object, typename IItemGroupObserver::FuncTraits< T >::FuncPtr funcptr)
Utility for simplified creation of ItemGroupObserverT.