Skip to content

Commit eb5bc37

Browse files
committed
Merge branch 'extend-class-registry'.
2 parents be0d90c + 6e7dfb7 commit eb5bc37

File tree

3 files changed

+149
-5
lines changed

3 files changed

+149
-5
lines changed

Diff for: src/diffpy/HasClassRegistry.hpp

+13-2
Original file line numberDiff line numberDiff line change
@@ -54,15 +54,26 @@ class HasClassRegistry
5454

5555
// methods provided by HasClassRegistry
5656

57-
/// Add a prototype of this instance to the registry
57+
/// Add a prototype of this instance to the registry.
5858
virtual bool registerThisType() const;
5959

60-
/// Make registered type tp available under a different alias
60+
/// Make registered type tp available under a different alias.
6161
static bool aliasType(const std::string& tp, const std::string& al);
6262

63+
/// Clear registration of the specified type under its standard name
64+
/// or any alias. Return the number of unset names and aliases or
65+
/// 0 if the specifed string type was not registered.
66+
static int deregisterType(const std::string& tp);
67+
6368
/// Create new instance of a specified string type.
6469
static SharedPtr createByType(const std::string& tp);
6570

71+
/// Return true if string is a registered string type or its alias.
72+
static bool isRegisteredType(const std::string& tp);
73+
74+
/// Return a map of string aliases to standard type strings.
75+
static std::map<std::string, std::string> getAliasedTypes();
76+
6677
/// Return a set of all registered string types
6778
static std::set<std::string> getRegisteredTypes();
6879

Diff for: src/diffpy/HasClassRegistry.ipp

+49-3
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,6 @@ bool HasClassRegistry<TBase>::registerThisType() const
3535
RegistryStorage& reg = getRegistry();
3636
if (reg.count(this->type()))
3737
{
38-
// do nothing when registering the same class twice
39-
const TBase& regprot = *(reg[this->type()]);
40-
if (typeid(*this) == typeid(regprot)) return true;
4138
// raise exception if trying to register a different class
4239
ostringstream emsg;
4340
emsg << "Prototype type '" << this->type() <<
@@ -77,6 +74,27 @@ bool HasClassRegistry<TBase>::aliasType(const std::string& tp,
7774
}
7875

7976

77+
template <class TBase>
78+
int HasClassRegistry<TBase>::deregisterType(const std::string& tp)
79+
{
80+
RegistryStorage& reg = getRegistry();
81+
typename RegistryStorage::iterator ii = reg.find(tp);
82+
if (ii == reg.end()) return 0;
83+
SharedPtr p = ii->second;
84+
int rv = 0;
85+
for (ii = reg.begin(); ii != reg.end();)
86+
{
87+
typename RegistryStorage::iterator jj = ii++;
88+
if (jj->second == p)
89+
{
90+
reg.erase(jj);
91+
++rv;
92+
}
93+
}
94+
return rv;
95+
}
96+
97+
8098
template <class TBase>
8199
typename HasClassRegistry<TBase>::SharedPtr
82100
HasClassRegistry<TBase>::createByType(const std::string& tp)
@@ -96,6 +114,34 @@ HasClassRegistry<TBase>::createByType(const std::string& tp)
96114
}
97115

98116

117+
template <class TBase>
118+
bool
119+
HasClassRegistry<TBase>::isRegisteredType(const std::string& tp)
120+
{
121+
const RegistryStorage& reg = getRegistry();
122+
return reg.count(tp);
123+
}
124+
125+
126+
template <class TBase>
127+
std::map<std::string, std::string>
128+
HasClassRegistry<TBase>::getAliasedTypes()
129+
{
130+
using namespace std;
131+
map<string, string> rv;
132+
const RegistryStorage& reg = getRegistry();
133+
typename RegistryStorage::const_iterator irg = reg.begin();
134+
for (; irg != reg.end(); ++irg)
135+
{
136+
if (irg->first != irg->second->type())
137+
{
138+
rv[irg->first] = irg->second->type();
139+
}
140+
}
141+
return rv;
142+
}
143+
144+
99145
template <class TBase>
100146
std::set<std::string>
101147
HasClassRegistry<TBase>::getRegisteredTypes()

Diff for: src/tests/TestHasClassRegistry.hpp

+87
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
/*****************************************************************************
2+
*
3+
* libdiffpy Complex Modeling Initiative
4+
* (c) 2016 Brookhaven Science Associates,
5+
* Brookhaven National Laboratory.
6+
* All rights reserved.
7+
*
8+
* File coded by: Pavol Juhas
9+
*
10+
* See AUTHORS.txt for a list of people who contributed.
11+
* See LICENSE.txt for license information.
12+
*
13+
******************************************************************************
14+
*
15+
* class TestHasClassRegistry -- test registration machinery for named classes.
16+
*
17+
*****************************************************************************/
18+
19+
#include <cxxtest/TestSuite.h>
20+
21+
#include <diffpy/srreal/ScatteringFactorTable.hpp>
22+
23+
using diffpy::srreal::ScatteringFactorTable;
24+
using diffpy::srreal::ScatteringFactorTablePtr;
25+
26+
//////////////////////////////////////////////////////////////////////////////
27+
// class TestHasClassRegistry
28+
//////////////////////////////////////////////////////////////////////////////
29+
30+
class TestHasClassRegistry : public CxxTest::TestSuite
31+
{
32+
private:
33+
34+
typedef diffpy::HasClassRegistry<ScatteringFactorTable> HCRBase;
35+
ScatteringFactorTablePtr msftb;
36+
HCRBase* mpreg;
37+
38+
public:
39+
40+
void setUp()
41+
{
42+
msftb = ScatteringFactorTable::createByType("xray");
43+
mpreg = msftb.get();
44+
}
45+
46+
void tearDown()
47+
{
48+
// restore SFTXray registration if removed in some test.
49+
msftb->deregisterType(msftb->type());
50+
msftb->registerThisType();
51+
TS_ASSERT(ScatteringFactorTable::isRegisteredType("X"));
52+
TS_ASSERT(ScatteringFactorTable::isRegisteredType("xray"));
53+
}
54+
55+
56+
void test_deregisterType()
57+
{
58+
TS_ASSERT_EQUALS(0,
59+
ScatteringFactorTable::deregisterType("invalid"));
60+
TS_ASSERT_EQUALS(2,
61+
ScatteringFactorTable::deregisterType("X"));
62+
TS_ASSERT(!(mpreg->isRegisteredType("xray")));
63+
TS_ASSERT(!(mpreg->isRegisteredType("X")));
64+
}
65+
66+
67+
void test_isRegisteredType()
68+
{
69+
TS_ASSERT(msftb->isRegisteredType("xray"));
70+
TS_ASSERT(ScatteringFactorTable::isRegisteredType("X"));
71+
TS_ASSERT_EQUALS(false, mpreg->isRegisteredType("invalid"));
72+
}
73+
74+
75+
void test_getAliasedTypes()
76+
{
77+
std::map<std::string, std::string> atps;
78+
atps = ScatteringFactorTable::getAliasedTypes();
79+
TS_ASSERT_EQUALS(4, atps.size());
80+
TS_ASSERT(atps.count("X"));
81+
TS_ASSERT_EQUALS("xray", atps["X"]);
82+
TS_ASSERT_EQUALS("electronnumber", atps["EN"]);
83+
}
84+
85+
}; // class TestHasClassRegistry
86+
87+
// End of file

0 commit comments

Comments
 (0)