Skip to content

Commit 4d29012

Browse files
committed
Add local class EmptyStructureAdapter.
This adapter type can only be empty. Use it for the singleton returned from emptyStructureAdapter(). This ensures that empty singleton cannot be broken by adding some atoms.
1 parent 682036d commit 4d29012

3 files changed

Lines changed: 212 additions & 9 deletions

File tree

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
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 EmptyStructureAdapter -- immutable class that is always empty.
16+
*
17+
*****************************************************************************/
18+
19+
#include <diffpy/serialization.ipp>
20+
#include <diffpy/srreal/StructureAdapter.hpp>
21+
22+
namespace diffpy {
23+
namespace srreal {
24+
25+
// Local constants -----------------------------------------------------------
26+
27+
namespace {
28+
29+
std::out_of_range outofrange("Index out of range.");
30+
31+
} // namespace
32+
33+
//////////////////////////////////////////////////////////////////////////////
34+
// class EmptyStructureAdapter
35+
//////////////////////////////////////////////////////////////////////////////
36+
37+
class EmptyStructureAdapter : public StructureAdapter
38+
{
39+
public:
40+
41+
// virtual methods from the base class
42+
43+
virtual StructureAdapterPtr clone() const
44+
{
45+
StructureAdapterPtr rv =
46+
boost::const_pointer_cast<StructureAdapter>(shared_from_this());
47+
return rv;
48+
}
49+
50+
51+
virtual BaseBondGeneratorPtr createBondGenerator() const
52+
{
53+
return boost::make_shared<BaseBondGenerator>(shared_from_this());
54+
}
55+
56+
57+
virtual int countSites() const
58+
{
59+
return 0;
60+
}
61+
62+
// reusing StructureAdapter::totalOccupancy()
63+
// reusing StructureAdapter::numberDensity()
64+
65+
virtual const std::string& siteAtomType(int idx) const
66+
{
67+
throw outofrange;
68+
}
69+
70+
71+
virtual const R3::Vector& siteCartesianPosition(int idx) const
72+
{
73+
throw outofrange;
74+
}
75+
76+
77+
virtual int siteMultiplicity(int idx) const
78+
{
79+
throw outofrange;
80+
}
81+
82+
83+
virtual double siteOccupancy(int idx) const
84+
{
85+
throw outofrange;
86+
}
87+
88+
89+
virtual bool siteAnisotropy(int idx) const
90+
{
91+
throw outofrange;
92+
}
93+
94+
95+
virtual const R3::Matrix& siteCartesianUij(int idx) const
96+
{
97+
throw outofrange;
98+
}
99+
100+
// reusing StructureAdapter::customPQConfig()
101+
// reusing StructureAdapter::diff()
102+
103+
private:
104+
105+
// serialization
106+
friend class boost::serialization::access;
107+
template<class Archive>
108+
void serialize(Archive& ar, const unsigned int version)
109+
{
110+
ar & boost::serialization::base_object<StructureAdapter>(*this);
111+
}
112+
113+
};
114+
115+
// Routines ------------------------------------------------------------------
116+
117+
StructureAdapterPtr emptyStructureAdapter()
118+
{
119+
static StructureAdapterPtr stru(new EmptyStructureAdapter);
120+
assert(stru && stru->countSites() == 0);
121+
return stru;
122+
}
123+
124+
} // namespace srreal
125+
} // namespace diffpy
126+
127+
BOOST_CLASS_EXPORT(diffpy::srreal::EmptyStructureAdapter)
128+
DIFFPY_INSTANTIATE_PTR_SERIALIZATION(diffpy::srreal::EmptyStructureAdapter)
129+
130+
// End of file

src/diffpy/srreal/StructureAdapter.cpp

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
#include <diffpy/serialization.ipp>
2424
#include <diffpy/mathutils.hpp>
2525
#include <diffpy/srreal/StructureAdapter.hpp>
26-
#include <diffpy/srreal/AtomicStructureAdapter.hpp>
2726
#include <diffpy/srreal/StructureDifference.hpp>
2827

2928
using namespace std;
@@ -80,14 +79,6 @@ StructureAdapter::diff(StructureAdapterConstPtr other) const
8079

8180
// Routines ------------------------------------------------------------------
8281

83-
StructureAdapterPtr emptyStructureAdapter()
84-
{
85-
static StructureAdapterPtr stru(new AtomicStructureAdapter);
86-
assert(stru && stru->countSites() == 0);
87-
return stru;
88-
}
89-
90-
9182
double meanSquareDisplacement(const R3::Matrix& Uijcartn,
9283
const R3::Vector& s, bool anisotropy)
9384
{
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
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 TestEmptyStructureAdapter -- test adapter that is always empty
16+
*
17+
*****************************************************************************/
18+
19+
#include <cxxtest/TestSuite.h>
20+
21+
#include <diffpy/srreal/AtomicStructureAdapter.hpp>
22+
#include "serialization_helpers.hpp"
23+
24+
namespace diffpy {
25+
namespace srreal {
26+
27+
using namespace std;
28+
29+
//////////////////////////////////////////////////////////////////////////////
30+
// class TestEmptyStructureAdapter
31+
//////////////////////////////////////////////////////////////////////////////
32+
33+
class TestEmptyStructureAdapter : public CxxTest::TestSuite
34+
{
35+
private:
36+
37+
StructureAdapterPtr mstru;
38+
39+
public:
40+
41+
void setUp()
42+
{
43+
mstru = emptyStructureAdapter();
44+
}
45+
46+
47+
void test_empty_instance()
48+
{
49+
TS_ASSERT_EQUALS(0, mstru->countSites());
50+
TS_ASSERT_EQUALS(mstru.get(), mstru->clone().get());
51+
TS_ASSERT_EQUALS(mstru, emptyStructureAdapter());
52+
TS_ASSERT_THROWS(mstru->siteAtomType(0), std::out_of_range);
53+
TS_ASSERT_THROWS(mstru->siteCartesianPosition(0),
54+
std::out_of_range);
55+
TS_ASSERT_THROWS(mstru->siteMultiplicity(0), std::out_of_range);
56+
TS_ASSERT_THROWS(mstru->siteOccupancy(0), std::out_of_range);
57+
TS_ASSERT_THROWS(mstru->siteAnisotropy(0), std::out_of_range);
58+
TS_ASSERT_THROWS(mstru->siteCartesianPosition(0),
59+
std::out_of_range);
60+
}
61+
62+
63+
void test_serialization()
64+
{
65+
StructureAdapterPtr stru1;
66+
stru1 = dumpandload(mstru);
67+
AtomicStructureAdapterPtr astru1 =
68+
boost::dynamic_pointer_cast<AtomicStructureAdapter>(stru1);
69+
TS_ASSERT(!astru1);
70+
TS_ASSERT_EQUALS(0, stru1->countSites());
71+
TS_ASSERT_EQUALS(stru1, stru1->clone());
72+
TS_ASSERT_THROWS(mstru->siteAtomType(0), std::out_of_range);
73+
}
74+
75+
}; // class TestEmptyStructureAdapter
76+
77+
} // namespace srreal
78+
} // namespace diffpy
79+
80+
using diffpy::srreal::TestEmptyStructureAdapter;
81+
82+
// End of file

0 commit comments

Comments
 (0)