Skip to content

Commit

Permalink
Add ancestor count concept
Browse files Browse the repository at this point in the history
Useful in cases where we want to enumerate contexts and keep track of how deep we are, as in the case of printing a tree representation of contexts.
  • Loading branch information
codemercenary committed May 6, 2016
1 parent a23189d commit dfbd19d
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 6 deletions.
3 changes: 2 additions & 1 deletion src/autowiring/CoreContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ static thread_specific_ptr<std::shared_ptr<CoreContext>> autoCurrentContext;
CoreContext::CoreContext(const std::shared_ptr<CoreContext>& pParent, t_childList::iterator backReference, auto_id sigilType) :
m_pParent(pParent),
m_backReference(backReference),
m_sigilType(sigilType),
SigilType(sigilType),
AncestorCount(pParent ? pParent->AncestorCount + 1 : 0),
m_stateBlock(std::make_shared<CoreContextStateBlock>(pParent ? pParent->m_stateBlock : nullptr))
{}

Expand Down
13 changes: 8 additions & 5 deletions src/autowiring/CoreContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -147,16 +147,19 @@ class CoreContext:
/// \sa AutoGlobalContext, GlobalCoreContext
static std::shared_ptr<CoreContext> GetGlobal(void);

// The number of ancestors of this context. The global context is defined to have zero ancestors.
const size_t AncestorCount = 0;

// Sigil type, used during bolting
const auto_id SigilType;

protected:
// A pointer to the parent context
const std::shared_ptr<CoreContext> m_pParent;

// Back-referencing iterator which refers to ourselves in our parent's child list:
const t_childList::iterator m_backReference;

// Sigil type, used during bolting
const auto_id m_sigilType;

// State block for this context:
std::shared_ptr<autowiring::CoreContextStateBlock> m_stateBlock;

Expand Down Expand Up @@ -394,7 +397,7 @@ class CoreContext:
/// The number of child contexts of this context.
size_t GetChildCount(void) const;
/// The type used as a sigil when creating this class, if any.
auto_id GetSigilType(void) const { return m_sigilType; }
auto_id GetSigilType(void) const { return SigilType; }
/// The Context iterator for the parent context's children, pointing to this context.
t_childList::iterator GetBackReference(void) const { return m_backReference; }
/// A shared reference to the parent context of this context.
Expand All @@ -411,7 +414,7 @@ class CoreContext:

/// True if the sigil type of this CoreContext matches the specified sigil type.
template<class Sigil>
bool Is(void) const { return m_sigilType == auto_id_t<Sigil>{}; }
bool Is(void) const { return SigilType == auto_id_t<Sigil>{}; }

/// <summary>
/// The first child in the set of this context's children.
Expand Down
17 changes: 17 additions & 0 deletions src/autowiring/test/CoreContextTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -698,3 +698,20 @@ TEST_F(CoreContextTest, SimultaneousMultiInject) {
// Verify that there's no config block still present
ASSERT_NO_THROW(ctxt->Config.Get("c"));
}


TEST_F(CoreContextTest, AncestorCount) {
AutoCurrentContext ctxt;

size_t ancestorCount = 0;
for (std::shared_ptr<CoreContext> cur = ctxt; cur; cur = cur->GetParentContext())
ancestorCount++;
ASSERT_EQ(ancestorCount, ctxt->AncestorCount) << "Manual traversal of the ancestor count did not match the annotated count";

AutoCreateContext child1;
AutoCreateContext child2{ child1 };
AutoCreateContext child3{ child2 };
ASSERT_EQ(ctxt->AncestorCount + 1, child1->AncestorCount);
ASSERT_EQ(ctxt->AncestorCount + 2, child2->AncestorCount);
ASSERT_EQ(ctxt->AncestorCount + 3, child3->AncestorCount);
}
1 change: 1 addition & 0 deletions src/autowiring/test/GlobalInitTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ void GlobalInitTest::SetUp(void) {

void GlobalInitTest::TearDown(void) {
std::shared_ptr<GlobalCoreContext> glbl = AutoGlobalContext();
ASSERT_EQ(0U, glbl->AncestorCount) << "Global context ancestor count must be exactly zero";

{
// Always drop the global context when tests are done
Expand Down

0 comments on commit dfbd19d

Please sign in to comment.