Skip to content
Snippets Groups Projects
Commit d6f4ae5e authored by Jan Trávníček's avatar Jan Trávníček
Browse files

fully generic container converter

parent fe678b1e
No related branches found
No related tags found
No related merge requests found
/*
* StringContainerConverter.h
*
* Created on: 7. 4. 2015
* Author: Jan Travnicek
*/
#ifndef _STRING_CONTAINER_CONVERTER__H_
#define _STRING_CONTAINER_CONVERTER__H_
#include <exception/AlibException.h>
#include "CastApi.hpp"
namespace common {
/* R is container<T>
* S is container<Wrapper>
* T is targetType
*/
template<class R, class S, class T>
class ContainerConverter {
public:
/**
* Performs conversion from contaier<String> to container<T>.
* @return container<T>.
*/
static R convert(const S& containerOfStrings);
};
template<class R, class S, class T>
R ContainerConverter<R, S, T>::convert(const S& container) {
R result;
auto inserter = std::inserter(result, result.end());
for(const auto& elem : container) {
alib::Object res = alib::castApi::getCastPool<T>().cast(elem.getData());
inserter = std::move((T&) res.getData());
}
return result;
}
} /* namespace common */
#endif /* _STRING_CONTAINER_CONVERTER__H_ */
/*
* StringContainerConverter.h
*
* Created on: 7. 4. 2015
* Author: Jan Travnicek
*/
#ifndef _STRING_CONTAINER_CONVERTER__H_
#define _STRING_CONTAINER_CONVERTER__H_
#include <string/LinearString.h>
#include <string/CyclicString.h>
#include <string/Epsilon.h>
#include <string/String.h>
#include <exception/AlibException.h>
namespace common {
/* R is container<T>
* S is container<String>
* T is Epsilon, LinearString, or CyclicString
*/
template<class R, class S, class T>
class StringContainerConverter : public string::VisitableStringBase::const_visitor_type {
public:
StringContainerConverter() {}
/**
* Performs conversion from contaier<String> to container<T>.
* @return container<T>.
*/
static R convert(const S& containerOfStrings);
private:
void Visit(void*, const string::Epsilon& text) const;
void Visit(void*, const string::LinearString& text) const;
void Visit(void*, const string::CyclicString& text) const;
static const StringContainerConverter<R, S, T> STRING_CONTAINER_CONVERTER;
};
template<class R, class S, class T>
R StringContainerConverter<R, S, T>::convert(const S& containerOfStrings) {
R result;
auto inserter = std::inserter(result, result.end());
for(const string::String& elem : containerOfStrings) {
T* out;
elem.getData().Accept((void*) &out, StringContainerConverter<R, S, T>::STRING_CONTAINER_CONVERTER);
inserter = std::move(*out);
delete out;
}
return result;
}
template<class R, class S, class T,
typename std::enable_if< std::is_constructible<T, string::Epsilon>::value >::type* = nullptr >
inline void VisitHelper(void* data, const string::Epsilon& text) {
T* & out = *((T**) data);
out = new T(text);
}
template<class R, class S, class T,
typename std::enable_if< ! std::is_constructible<T, string::Epsilon>::value >::type* = nullptr >
inline void VisitHelper(void*, const string::Epsilon&) {
throw exception::AlibException("Unsupported string type Epsilon");
}
template<class R, class S, class T>
void StringContainerConverter<R, S, T>::Visit(void* data, const string::Epsilon& text) const {
VisitHelper<R, S, T>(data, text);
}
template<class R, class S, class T,
typename std::enable_if< std::is_constructible<T, string::LinearString>::value >::type* = nullptr >
inline void VisitHelper(void* data, const string::LinearString& text) {
T* & out = *((T**) data);
out = new T(text);
}
template<class R, class S, class T,
typename std::enable_if< ! std::is_constructible<T, string::LinearString>::value >::type* = nullptr >
inline void VisitHelper(void*, const string::LinearString&) {
throw exception::AlibException("Unsupported string type LinearString");
}
template<class R, class S, class T>
void StringContainerConverter<R, S, T>::Visit(void* data, const string::LinearString& text) const {
VisitHelper<R, S, T>(data, text);
}
template<class R, class S, class T,
typename std::enable_if< std::is_constructible<T, string::CyclicString>::value >::type* = nullptr >
inline void VisitHelper(void* data, const string::CyclicString& text) {
T* & out = *((T**) data);
out = new T(text);
}
template<class R, class S, class T,
typename std::enable_if< ! std::is_constructible<T, string::CyclicString>::value >::type* = nullptr >
inline void VisitHelper(void*, const string::CyclicString&) {
throw exception::AlibException("Unsupported string type CyclicString");
}
template<class R, class S, class T>
void StringContainerConverter<R, S, T>::Visit(void* data, const string::CyclicString& text) const {
VisitHelper<R, S, T>(data, text);
}
template<class R, class S, class T>
const StringContainerConverter<R, S, T> StringContainerConverter<R, S, T>::STRING_CONTAINER_CONVERTER;
} /* namespace common */
#endif /* _STRING_CONTAINER_CONVERTER__H_ */
...@@ -9,14 +9,14 @@ ...@@ -9,14 +9,14 @@
#include <exception/AlibException.h> #include <exception/AlibException.h>
#include <string/LinearString.h> #include <string/LinearString.h>
#include <string/Epsilon.h> #include <string/Epsilon.h>
#include "../../common/StringContainerConverter.hpp" #include "../../common/ContainerConverter.hpp"
   
namespace stringology { namespace stringology {
   
namespace exact { namespace exact {
   
automaton::Automaton ExactMultiNondeterministicSubsequenceAutomaton::construct(const std::set<string::String>& texts) { automaton::Automaton ExactMultiNondeterministicSubsequenceAutomaton::construct(const std::set<string::String>& texts) {
return automaton::Automaton(ExactMultiNondeterministicSubsequenceAutomaton::construct(common::StringContainerConverter<std::set<string::LinearString>, std::set<string::String>, string::LinearString>::convert(texts))); return automaton::Automaton(ExactMultiNondeterministicSubsequenceAutomaton::construct(common::ContainerConverter<std::set<string::LinearString>, std::set<string::String>, string::LinearString>::convert(texts)));
} }
   
automaton::EpsilonNFA ExactMultiNondeterministicSubsequenceAutomaton::construct(const std::set<string::LinearString>& texts) { automaton::EpsilonNFA ExactMultiNondeterministicSubsequenceAutomaton::construct(const std::set<string::LinearString>& texts) {
......
...@@ -51,7 +51,7 @@ public: ...@@ -51,7 +51,7 @@ public:
   
virtual int compare(const T & other) const = 0; virtual int compare(const T & other) const = 0;
   
template<typename R, typename S> template<typename R, typename S> //TODO what if someone want to control the ordering?
static int compare(const R& first, const S& second) { static int compare(const R& first, const S& second) {
if(first.selfTypeId() < second.selfTypeId()) if(first.selfTypeId() < second.selfTypeId())
return -1; return -1;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment