Skip to content

Commit b5c8fe2

Browse files
committed
refactoring, removing dynamic casts
1 parent aa19b4c commit b5c8fe2

3 files changed

Lines changed: 78 additions & 54 deletions

File tree

include/libfolia/folia_subclasses.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,7 @@ public: \
260260
set_cls( "current" );
261261
return res;
262262
}
263+
bool addable( const FoliaElement * ) const override;
263264
FoliaElement *postappend() override;
264265
private:
265266
FoliaElement *find_default_reference() const override;
@@ -670,6 +671,7 @@ public: \
670671
ADD_DEFAULT_CONSTRUCTORS( WordReference, AbstractWord );
671672
FoliaElement *ref() const { return _ref; };
672673
std::string tval() const { return _tval; };
674+
bool addable( const FoliaElement * ) const override;
673675
private:
674676
FoliaElement *parseXml( const xmlNode *node ) override;
675677
xmlNode *xml( bool, bool=false ) const override;

src/folia_impl.cxx

Lines changed: 2 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -3280,8 +3280,7 @@ namespace folia {
32803280
}
32813281
}
32823282
if ( _parent &&
3283-
!( isinstance<WordReference>()
3284-
|| referable() ) ){
3283+
!referable() ){
32853284
throw XmlError( this,
32863285
"attempt to reconnect node " + classname() + "("
32873286
+ id()
@@ -3290,58 +3289,7 @@ namespace folia {
32903289
+ ", it was already connected to a "
32913290
+ parent->classname() + " id=" + parent->id() );
32923291
}
3293-
if ( isinstance<TextContent>() ) {
3294-
string my_cls = cls();
3295-
if ( parent->isinstance<Word>() ) {
3296-
string val = str(my_cls);
3297-
val = trim( val );
3298-
if ( val.empty() ) {
3299-
// we have to check for a child with the IMPLICITSPACE property
3300-
// ONLY in that case, an "empty" text is allowed.
3301-
auto implicit = []( auto elt ){ return elt->implicitspace(); };
3302-
bool has_implicit = std::any_of( _data.begin(), _data.end(),
3303-
implicit );
3304-
if ( !has_implicit ){
3305-
throw ValueError( this,
3306-
"attempt to add an empty <t> to word: "
3307-
+ parent->id() );
3308-
}
3309-
}
3310-
}
3311-
string st = sett();
3312-
vector<TextContent*> tmp
3313-
= parent->select<TextContent>( st,
3314-
SELECT_FLAGS::LOCAL );
3315-
if ( any_of( tmp.cbegin(),
3316-
tmp.cend(),
3317-
[my_cls]( const TextContent *t) { return ( t->cls() == my_cls);} ) ){
3318-
throw DuplicateAnnotationError( this,
3319-
"attempt to add <t> with class="
3320-
+ my_cls + " to element: "
3321-
+ parent->id()
3322-
+ " which already has a <t> with that class" );
3323-
}
3324-
}
3325-
if ( isinstance<WordReference>() ){
3326-
const WordReference *me = dynamic_cast<const WordReference*>(this);
3327-
string tatt = me->tval();
3328-
if ( !tatt.empty() ){
3329-
string watt = me->ref()->str(parent->textclass());
3330-
if ( watt.empty() ){
3331-
string msg = "no matching 't' value found in the '<w>' refered by "
3332-
"<wref id=\"" + me->ref()->id() + "\" t=\""+ tatt
3333-
+ "\"> for textclass '" + parent->textclass() + "'";
3334-
throw XmlError( this, msg );
3335-
}
3336-
else if ( watt != tatt ){
3337-
string msg = "the 't' value of <wref id=\"" + me->ref()->id()
3338-
+ "\" t=\""+ tatt + "\"> for textclass '" + parent->textclass()
3339-
+ "' doesn't match any value of the refered word for that class";
3340-
throw XmlError( this, msg );
3341-
}
3342-
}
3343-
}
3344-
if ( is_textcontainer() ||
3292+
if ( //is_textcontainer() ||
33453293
isinstance<Word>() ){
33463294
parent->check_append_text_consistency( this );
33473295
}

src/folia_subclasses.cxx

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,52 @@ namespace folia {
7878
return result;
7979
}
8080

81+
bool TextContent::addable( const FoliaElement *parent ) const {
82+
/// test if an TextContent might succesfully appended to \em parent
83+
/*!
84+
* \param parent the node to check
85+
* \return true if it doesn't throw
86+
*
87+
* \note It will allways throw an error, instead of returning false
88+
*/
89+
if ( AbstractElement::addable( parent ) ){
90+
string my_cls = cls();
91+
if ( parent->isinstance<Word>() ) {
92+
string val = str(my_cls);
93+
val = trim( val );
94+
if ( val.empty() ) {
95+
// we have to check for a child with the IMPLICITSPACE property
96+
// ONLY in that case, an "empty" text is allowed.
97+
auto implicit = []( auto elt ){ return elt->implicitspace(); };
98+
bool has_implicit = std::any_of( data().begin(), data().end(),
99+
implicit );
100+
if ( !has_implicit ){
101+
throw ValueError( this,
102+
"attempt to add an empty <t> to word: "
103+
+ parent->id() );
104+
}
105+
}
106+
}
107+
string st = sett();
108+
vector<TextContent*> tmp
109+
= parent->select<TextContent>( st,
110+
SELECT_FLAGS::LOCAL );
111+
if ( any_of( tmp.cbegin(),
112+
tmp.cend(),
113+
[my_cls]( const TextContent *t) { return ( t->cls() == my_cls);} ) ){
114+
throw DuplicateAnnotationError( this,
115+
"attempt to add <t> with class="
116+
+ my_cls + " to element: "
117+
+ parent->id()
118+
+ " which already has a <t> with that class" );
119+
}
120+
}
121+
if ( is_textcontainer() ){
122+
parent->check_append_text_consistency( this );
123+
}
124+
return true;
125+
}
126+
81127
FoliaElement *TextContent::postappend( ) {
82128
/// perform some extra checks after appending a TextContent
83129
if ( doc() ){
@@ -1386,6 +1432,34 @@ namespace folia {
13861432
return result;
13871433
}
13881434

1435+
bool WordReference::addable( const FoliaElement *parent ) const {
1436+
/// test if a reference might succesfully appended to \em parent
1437+
/*!
1438+
* \param parent the node to check
1439+
* \return true if it doesn't throw
1440+
*
1441+
* \note It will allways throw an error, instead of returning false
1442+
*/
1443+
if ( AbstractElement::addable( parent ) ){
1444+
if ( !_tval.empty() ){
1445+
string watt = _ref->str(parent->textclass());
1446+
if ( watt.empty() ){
1447+
string msg = "no matching 't' value found in the '<w>' refered by "
1448+
"<wref id=\"" + _ref->id() + "\" t=\""+ _tval
1449+
+ "\"> for textclass '" + parent->textclass() + "'";
1450+
throw XmlError( this, msg );
1451+
}
1452+
else if ( watt != _tval ){
1453+
string msg = "the 't' value of <wref id=\"" + _ref->id()
1454+
+ "\" t=\""+ _tval + "\"> for textclass '" + parent->textclass()
1455+
+ "' doesn't match any value of the refered word for that class";
1456+
throw XmlError( this, msg );
1457+
}
1458+
}
1459+
}
1460+
return true;
1461+
}
1462+
13891463
FoliaElement* WordReference::parseXml( const xmlNode *node ) {
13901464
/// parse a WordReference node at node
13911465
/*!

0 commit comments

Comments
 (0)