Skip to content

Commit

Permalink
More const in Registry.cpp
Browse files Browse the repository at this point in the history
  • Loading branch information
Paul-Licameli committed Apr 29, 2024
1 parent f99419a commit 4bfc457
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 41 deletions.
77 changes: 40 additions & 37 deletions libraries/lib-registries/Registry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,44 +38,46 @@ struct PlaceHolder : GroupItemBase {

struct CollectedItems
{
//! @invariant `!MergeLater() || dynamic_cast<GroupItemBase *>(&VisitNow())`
//! @invariant `!MergeLater() ||
//! dynamic_cast<const GroupItemBase *>(&VisitNow())`
class Item {
public:
Item(BaseItem &visitNow, OrderingHint hint = {})
Item(const BaseItem &visitNow, OrderingHint hint = {})
: mVisitNow{ &visitNow }, mHint{ hint }
{
assert(CheckInvariant());
}

BaseItem &VisitNow() const { return *mVisitNow; }
//! @pre !MergeLater() || dynamic_cast<GroupItemBase *>(&visitNow)
void SetVisitNow(BaseItem &visitNow)
const BaseItem &VisitNow() const { return *mVisitNow; }
//! @pre !MergeLater() || dynamic_cast<const GroupItemBase *>(&visitNow)
void SetVisitNow(const BaseItem &visitNow)
{
assert(!MergeLater() || dynamic_cast<GroupItemBase *>(&visitNow));
assert(!MergeLater() ||
dynamic_cast<const GroupItemBase *>(&visitNow));
mVisitNow = &visitNow;
assert(CheckInvariant());
}

const OrderingHint &Hint() const { return mHint; }

PlaceHolder *MergeLater() const { return mMergeLater; }
//! @pre dynamic_cast<GroupItemBase *>(&VisitNow())
//! @pre dynamic_cast<const GroupItemBase *>(&VisitNow())
void SetMergeLater(PlaceHolder &mergeLater)
{
assert(dynamic_cast<GroupItemBase *>(&VisitNow()));
assert(dynamic_cast<const GroupItemBase *>(&VisitNow()));
mMergeLater = &mergeLater;
assert(CheckInvariant());
}
private:
bool CheckInvariant() const
{
return mVisitNow &&
(!MergeLater() || dynamic_cast<GroupItemBase *>(&VisitNow()));
(!MergeLater() || dynamic_cast<const GroupItemBase *>(&VisitNow()));
}

// Predefined, or merged from registry already.
// @invariant not null
BaseItem *mVisitNow{};
const BaseItem *mVisitNow{};

// Ordering hint for the merged item:
OrderingHint mHint{};
Expand All @@ -85,7 +87,7 @@ struct CollectedItems
PlaceHolder *mMergeLater{};
};
std::vector< BaseItemSharedPtr > &computedItems;
std::vector< Item > items;
std::vector<Item> items;
std::unordered_set<Identifier> mResolvedConflicts;

// A linear search. Smarter search may not be worth the effort.
Expand All @@ -100,33 +102,33 @@ struct CollectedItems
}

auto InsertNewItemUsingPreferences(
const ItemOrdering &itemOrdering, BaseItem &item) -> bool;
const ItemOrdering &itemOrdering, const BaseItem &item) -> bool;

auto InsertNewItemUsingHint(ItemOrdering &itemOrdering,
BaseItem &item, const OrderingHint &hint, size_t endItemsCount,
const BaseItem &item, const OrderingHint &hint, size_t endItemsCount,
bool force )
-> bool;

auto MergeLater(Item &found, const Identifier &name,
GroupItemBase::Ordering ordering) -> PlaceHolder *;

void SubordinateSingleItem(Item &found, BaseItem &item);
void SubordinateSingleItem(Item &found, const BaseItem &item);

void SubordinateMultipleItems(Item &found, GroupItemBase &items);
void SubordinateMultipleItems(Item &found, const GroupItemBase &items);

auto MergeWithExistingItem(const ItemOrdering &itemOrdering,
BaseItem &item, OrderingHint::ConflictResolutionPolicy policy) -> bool;
const BaseItem &item, OrderingHint::ConflictResolutionPolicy policy) -> bool;

class NewItem {
public:
NewItem(BaseItem &item, OrderingHint hint)
NewItem(const BaseItem &item, OrderingHint hint)
: mpItem{ &item }, mHint{ hint }
{}
BaseItem &Item() const { return *mpItem; }
const BaseItem &Item() const { return *mpItem; }
const OrderingHint &Hint() const { return mHint; }
private:
//! @invariant not null
BaseItem *mpItem;
const BaseItem *mpItem;
OrderingHint mHint;
};
using NewItems = std::vector<NewItem>;
Expand All @@ -152,7 +154,7 @@ struct CollectedItems
// When a computed or indirect item, or nameless grouping, specifies a hint and
// the subordinate does not, propagate the hint.
// Likewise for conflict resolution.
OrderingHint ChooseHint(BaseItem *delegate, const OrderingHint &hint)
OrderingHint ChooseHint(const BaseItem *delegate, const OrderingHint &hint)
{
auto result =
!delegate || delegate->orderingHint.type == OrderingHint::Unspecified
Expand All @@ -173,7 +175,7 @@ OrderingHint ChooseHint(BaseItem *delegate, const OrderingHint &hint)
// alternate as the entire tree is recursively visited.

// forward declaration for mutually recursive functions
void CollectItem(CollectedItems &collection, BaseItem &item,
void CollectItem(CollectedItems &collection, const BaseItem &item,
const OrderingHint &hint, void *pComputedItemContext);
void CollectItems(CollectedItems &collection, const GroupItemBase &items,
const OrderingHint &hint, void *pComputedItemContext)
Expand All @@ -184,11 +186,11 @@ void CollectItems(CollectedItems &collection, const GroupItemBase &items,
ChooseHint(item.get(), hint), pComputedItemContext);
}
void CollectItem(CollectedItems &collection,
BaseItem &item, const OrderingHint &hint, void *pComputedItemContext)
const BaseItem &item, const OrderingHint &hint, void *pComputedItemContext)
{
using namespace Registry;
if (const auto pIndirect =
dynamic_cast<IndirectItemBase*>(&item)) {
dynamic_cast<const IndirectItemBase*>(&item)) {
auto delegate = pIndirect->ptr.get();
if (delegate)
// recursion
Expand All @@ -198,7 +200,7 @@ void CollectItem(CollectedItems &collection,
}
else
if (const auto pComputed =
dynamic_cast<ComputedItemBase*>(&item)) {
dynamic_cast<const ComputedItemBase*>(&item)) {
auto result = pComputed->factory(pComputedItemContext);
if (result) {
// Guarantee long enough lifetime of the result
Expand All @@ -210,7 +212,7 @@ void CollectItem(CollectedItems &collection,
}
}
else
if (auto pGroup = dynamic_cast<GroupItemBase*>(&item)) {
if (auto pGroup = dynamic_cast<const GroupItemBase*>(&item)) {
if (pGroup->GetOrdering() == GroupItemBase::Anonymous)
// anonymous grouping item is transparent to path calculations
// collect group members now
Expand All @@ -224,7 +226,7 @@ void CollectItem(CollectedItems &collection,
}
else {
// Exhaustive type switch
assert(dynamic_cast<SingleItem*>(&item));
assert(dynamic_cast<const SingleItem*>(&item));
// common to all single items
collection.items.push_back({ item, hint });
}
Expand Down Expand Up @@ -373,7 +375,7 @@ struct ItemOrdering {
// preferences done at the very end of the visitation.
// This function will succeed whenever the item's name is in the ordering.
auto CollectedItems::InsertNewItemUsingPreferences(
const ItemOrdering &itemOrdering, BaseItem &item)
const ItemOrdering &itemOrdering, const BaseItem &item)
-> bool
{
// Note that if more than one plug-in registers items under the same
Expand Down Expand Up @@ -418,7 +420,7 @@ auto CollectedItems::InsertNewItemUsingPreferences(
// For each group node, this may be called in the second and later passes
// of merging of items. It will succeed if force is true.
auto CollectedItems::InsertNewItemUsingHint(ItemOrdering &itemOrdering,
BaseItem &item, const OrderingHint &hint, size_t endItemsCount,
const BaseItem &item, const OrderingHint &hint, size_t endItemsCount,
bool force ) -> bool
{
auto begin = items.begin(), end = items.end(),
Expand Down Expand Up @@ -497,7 +499,7 @@ auto CollectedItems::InsertNewItemUsingHint(ItemOrdering &itemOrdering,
auto CollectedItems::MergeLater(Item &found, const Identifier &name,
GroupItemBase::Ordering ordering) -> PlaceHolder *
{
assert(dynamic_cast<GroupItemBase*>(&found.VisitNow()));
assert(dynamic_cast<const GroupItemBase*>(&found.VisitNow()));
// Therefore found.SetMergeLater can be called

auto subGroup = found.MergeLater();
Expand All @@ -511,19 +513,20 @@ auto CollectedItems::MergeLater(Item &found, const Identifier &name,
}

//! @pre `found.VisitNow()` is a GroupItemBase
void CollectedItems::SubordinateSingleItem(Item &found, BaseItem &item)
void CollectedItems::SubordinateSingleItem(Item &found, const BaseItem &item)
{
assert(dynamic_cast<GroupItemBase*>(&found.VisitNow()));
assert(dynamic_cast<const GroupItemBase*>(&found.VisitNow()));
MergeLater(found, item.name, GroupItemBase::Weak)->push_back(
std::make_unique<IndirectItemBase>(
// shared pointer with vacuous deleter
std::shared_ptr<BaseItem>(&item, [](void*){})));
std::shared_ptr<const BaseItem>(&item, [](const void*){})));
}

//! @pre `found.VisitNow()` is a GroupItemBase
void CollectedItems::SubordinateMultipleItems(Item &found, GroupItemBase &items)
void CollectedItems::SubordinateMultipleItems(Item &found,
const GroupItemBase &items)
{
assert(dynamic_cast<GroupItemBase*>(&found.VisitNow()));
assert(dynamic_cast<const GroupItemBase*>(&found.VisitNow()));
auto subGroup = MergeLater(found, items.name, items.GetOrdering());
for (const auto &pItem : items)
subGroup->push_back(std::make_unique<IndirectItemBase>(
Expand All @@ -532,7 +535,7 @@ void CollectedItems::SubordinateMultipleItems(Item &found, GroupItemBase &items)
}

auto CollectedItems::MergeWithExistingItem(const ItemOrdering &itemOrdering,
BaseItem &item, OrderingHint::ConflictResolutionPolicy policy) -> bool
const BaseItem &item, OrderingHint::ConflictResolutionPolicy policy) -> bool
{
// Assume no null pointers remain after CollectItems:
const auto &name = item.name;
Expand All @@ -541,9 +544,9 @@ auto CollectedItems::MergeWithExistingItem(const ItemOrdering &itemOrdering,
// Collision of names between collection and registry!
// There are 2 * 2 = 4 cases, as each of the two are group items or
// not.
const auto pRegistryGroup = dynamic_cast<GroupItemBase *>(&item);
const auto pRegistryGroup = dynamic_cast<const GroupItemBase *>(&item);
if (const auto pCollectionGroup =
dynamic_cast<GroupItemBase *>(&found->VisitNow()))
dynamic_cast<const GroupItemBase *>(&found->VisitNow()))
{
// Therefore preconditions of Subordinate calls below are satisfied
if (pRegistryGroup) {
Expand Down
8 changes: 4 additions & 4 deletions libraries/lib-registries/Registry.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,17 +110,17 @@ namespace detail { using namespace TypeList;
};

using BaseItemPtr = std::unique_ptr<BaseItem>;

using BaseItemSharedPtr = std::shared_ptr<BaseItem>;
using BaseItemSharedPtr = std::shared_ptr<BaseItem>;
using ConstBaseItemSharedPtr = std::shared_ptr<const BaseItem>;

struct REGISTRIES_API IndirectItemBase : BaseItem {
explicit IndirectItemBase(const BaseItemSharedPtr &ptr)
explicit IndirectItemBase(const ConstBaseItemSharedPtr &ptr)
: BaseItem{ wxEmptyString }
, ptr{ ptr }
{}
~IndirectItemBase() override;

BaseItemSharedPtr ptr;
ConstBaseItemSharedPtr ptr;
};

struct ComputedItemBase;
Expand Down

0 comments on commit 4bfc457

Please sign in to comment.