Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Corryvreckan
Corryvreckan
Commits
82b93bd4
Commit
82b93bd4
authored
Jul 03, 2018
by
Simon Spannagel
Browse files
Merge branch 'master' into clicpix2-analysis
parents
27eb4032
017ba963
Pipeline
#434415
passed with stages
in 4 minutes and 19 seconds
Changes
14
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
src/core/CMakeLists.txt
View file @
82b93bd4
...
...
@@ -7,6 +7,7 @@ ADD_LIBRARY(CorryvreckanCore SHARED
detector/Detector.cpp
utils/log.cpp
utils/unit.cpp
utils/text.cpp
clipboard/Clipboard.cpp
config/ConfigManager.cpp
config/ConfigReader.cpp
...
...
src/core/config/Configuration.hpp
View file @
82b93bd4
...
...
@@ -16,7 +16,7 @@
#include <string>
#include <vector>
#include "core/utils/
string
.h"
#include "core/utils/
text
.h"
#include "exceptions.h"
namespace
corryvreckan
{
...
...
@@ -142,12 +142,21 @@ namespace corryvreckan {
// TODO [doc] Provide second template parameter to specify the vector type to return it in
std
::
vector
<
std
::
string
>
getPathArray
(
const
std
::
string
&
key
,
bool
check_exists
=
false
)
const
;
/**
* @brief Set value for a key in a given type with units
* @param key Key to set value of
* @param val Value to assign to the key
* @param units List of possible output units
*/
template
<
typename
T
>
void
set
(
const
std
::
string
&
key
,
const
T
&
val
,
std
::
initializer_list
<
std
::
string
>
units
);
/**
* @brief Set value for a key in a given type
* @param key Key to set value of
* @param val Value to assign to the key
*/
template
<
typename
T
>
void
set
(
const
std
::
string
&
key
,
const
T
&
val
);
/**
* @brief Set list of values for a key in a given type
* @param key Key to set values of
...
...
src/core/config/Configuration.tpp
View file @
82b93bd4
...
...
@@ -129,14 +129,29 @@ namespace corryvreckan {
template
<
typename
T
>
void
Configuration
::
set
(
const
std
::
string
&
key
,
const
T
&
val
)
{
config_
[
key
]
=
corryvreckan
::
to_string
(
val
);
}
template
<
typename
T
>
void
Configuration
::
set
(
const
std
::
string
&
key
,
const
T
&
val
,
std
::
initializer_list
<
std
::
string
>
units
)
{
auto
split
=
corryvreckan
::
split
<
Units
::
UnitType
>
(
corryvreckan
::
to_string
(
val
));
std
::
string
ret_str
;
for
(
auto
&
element
:
split
)
{
ret_str
+=
Units
::
display
(
element
,
units
);
ret_str
+=
","
;
}
ret_str
.
pop_back
();
config_
[
key
]
=
ret_str
;
}
template
<
typename
T
>
void
Configuration
::
setArray
(
const
std
::
string
&
key
,
const
std
::
vector
<
T
>&
val
)
{
// NOTE: not the most elegant way to support arrays
std
::
string
str
;
for
(
auto
&
el
:
val
)
{
str
+=
corryvreckan
::
to_string
(
el
);
str
+=
","
;
str
+=
corryvreckan
::
to_string
(
val
);
}
set
(
key
,
str
);
str
.
pop_back
();
config_
[
key
]
=
str
;
}
template
<
typename
T
>
void
Configuration
::
setDefault
(
const
std
::
string
&
key
,
const
T
&
val
)
{
...
...
src/core/detector/Detector.cpp
View file @
82b93bd4
...
...
@@ -48,9 +48,9 @@ Detector::Detector(const Configuration& config) {
this
->
initialise
();
LOG
(
TRACE
)
<<
"Initialized
\"
"
<<
m_detectorType
<<
"
\"
: "
<<
m_nPixelsX
<<
"x"
<<
m_nPixelsY
<<
" px, pitch of "
<<
display
_vector
(
m_pitch
,
{
"mm"
,
"um"
});
LOG
(
TRACE
)
<<
" Position: "
<<
display
_vector
(
m_displacement
,
{
"mm"
,
"um"
});
LOG
(
TRACE
)
<<
" Orientation: "
<<
display
_vector
(
m_orientation
,
{
"deg"
})
<<
" ("
<<
m_orientation_mode
<<
")"
;
<<
Units
::
display
(
m_pitch
,
{
"mm"
,
"um"
});
LOG
(
TRACE
)
<<
" Position: "
<<
Units
::
display
(
m_displacement
,
{
"mm"
,
"um"
});
LOG
(
TRACE
)
<<
" Orientation: "
<<
Units
::
display
(
m_orientation
,
{
"deg"
})
<<
" ("
<<
m_orientation_mode
<<
")"
;
if
(
m_timingOffset
>
0.
)
{
LOG
(
TRACE
)
<<
"Timing offset: "
<<
m_timingOffset
;
}
...
...
@@ -155,17 +155,17 @@ Configuration Detector::getConfiguration() {
Configuration
config
(
name
());
config
.
set
(
"type"
,
m_detectorType
);
config
.
set
(
"position"
,
m_displacement
);
config
.
set
(
"position"
,
m_displacement
,
{
"um"
,
"mm"
}
);
config
.
set
(
"orientation_mode"
,
m_orientation_mode
);
config
.
set
(
"orientation"
,
m_orientation
);
config
.
set
(
"orientation"
,
m_orientation
,
{
"deg"
}
);
auto
npixels
=
ROOT
::
Math
::
DisplacementVector2D
<
Cartesian2D
<
int
>>
(
m_nPixelsX
,
m_nPixelsY
);
config
.
set
(
"number_of_pixels"
,
npixels
);
// Size of the pixels
config
.
set
(
"pixel_pitch"
,
m_pitch
);
config
.
set
(
"pixel_pitch"
,
m_pitch
,
{
"um"
}
);
if
(
m_timingOffset
!=
0.
)
{
config
.
set
(
"time_offset"
,
m_timingOffset
);
config
.
set
(
"time_offset"
,
m_timingOffset
,
{
"ns"
,
"us"
,
"ms"
,
"s"
}
);
}
if
(
!
m_maskfile_name
.
empty
())
{
...
...
src/core/utils/ROOT.h
View file @
82b93bd4
...
...
@@ -22,7 +22,7 @@
#include <Math/PositionVector3D.h>
#include <TString.h>
#include "core/utils/
string
.h"
#include "core/utils/
text
.h"
#include "core/utils/type.h"
namespace
corryvreckan
{
...
...
@@ -146,21 +146,6 @@ namespace corryvreckan {
inline
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
const
ROOT
::
Math
::
PositionVector2D
<
T
,
U
>&
vec
)
{
return
os
<<
"("
<<
vec
.
x
()
<<
","
<<
vec
.
y
()
<<
")"
;
}
/**
* @brief Utility function to display vector types with units
* @note Works for all vector types that can be converted to string using \ref StringConversions "the string utilities".
*/
template
<
typename
T
>
inline
std
::
string
display_vector
(
T
inp
,
std
::
initializer_list
<
std
::
string
>
units
)
{
auto
split
=
corryvreckan
::
split
<
Units
::
UnitType
>
(
corryvreckan
::
to_string
(
inp
));
std
::
string
ret_str
=
"("
;
for
(
auto
&
element
:
split
)
{
ret_str
+=
Units
::
display
(
element
,
units
);
ret_str
+=
","
;
}
ret_str
[
ret_str
.
size
()
-
1
]
=
')'
;
return
ret_str
;
}
}
// namespace corryvreckan
#endif
/* CORRYVRECKAN_ROOT_H */
src/core/utils/text.cpp
0 → 100644
View file @
82b93bd4
/**
* @file
* @brief Implementation of string utilities
*
* @copyright Copyright (c) 2017 CERN and the Allpix Squared authors.
* This software is distributed under the terms of the MIT License, copied verbatim in the file "LICENSE.md".
* In applying this license, CERN does not waive the privileges and immunities granted to it by virtue of its status as an
* Intergovernmental Organization or submit itself to any jurisdiction.
*
* Used extensively for parsing the configuration in the \ref corryvreckan::ConfigReader.
*/
#include "text.h"
#include "unit.h"
using
namespace
corryvreckan
;
std
::
string
corryvreckan
::
trim
(
const
std
::
string
&
str
,
const
std
::
string
&
delims
)
{
size_t
b
=
str
.
find_first_not_of
(
delims
);
size_t
e
=
str
.
find_last_not_of
(
delims
);
if
(
b
==
std
::
string
::
npos
||
e
==
std
::
string
::
npos
)
{
return
""
;
}
return
std
::
string
(
str
,
b
,
e
-
b
+
1
);
}
std
::
string
corryvreckan
::
from_string_helper
(
std
::
string
str
)
{
// Check if string is not empty
str
=
trim
(
str
);
if
(
str
.
empty
())
{
throw
std
::
invalid_argument
(
"string is empty"
);
}
// Check if there is whitespace in the string
size_t
white_space
=
str
.
find_first_of
(
"
\t\n\r\v
"
);
if
(
white_space
!=
std
::
string
::
npos
)
{
throw
std
::
invalid_argument
(
"remaining data at end"
);
}
return
str
;
}
/**
* If a pair of enclosing double quotation marks is found, the whole string within the quotation marks is returned.
* Otherwise only the first part is read until whitespace is encountered.
*/
std
::
string
corryvreckan
::
from_string_impl
(
std
::
string
str
,
type_tag
<
std
::
string
>
)
{
str
=
trim
(
str
);
// If there are "" then we should take the whole string
if
(
!
str
.
empty
()
&&
(
str
.
front
()
==
'\"'
||
str
.
front
()
==
'\''
))
{
if
(
str
.
find
(
str
.
front
(),
1
)
!=
str
.
size
()
-
1
)
{
throw
std
::
invalid_argument
(
"remaining data at end"
);
}
return
str
.
substr
(
1
,
str
.
size
()
-
2
);
}
// Otherwise read a single string
return
from_string_helper
(
str
);
}
/**
* Both numerical (0, 1) and textual representations ("false", "true") are supported for booleans. No enclosing quotation
* marks should be used.
*/
bool
corryvreckan
::
from_string_impl
(
std
::
string
str
,
type_tag
<
bool
>
)
{
str
=
from_string_helper
(
str
);
std
::
istringstream
sstream
(
str
);
bool
ret_value
=
false
;
if
(
isalpha
(
str
.
back
())
!=
0
)
{
sstream
>>
std
::
boolalpha
>>
ret_value
;
}
else
{
sstream
>>
ret_value
;
}
// Check if the reading was succesfull and everything was read
if
(
sstream
.
fail
()
||
sstream
.
peek
()
!=
EOF
)
{
throw
std
::
invalid_argument
(
"conversion not possible"
);
}
return
ret_value
;
}
src/core/utils/
string
.h
→
src/core/utils/
text
.h
View file @
82b93bd4
...
...
@@ -6,7 +6,7 @@
* In applying this license, CERN does not waive the privileges and immunities granted to it by virtue of its status as an
* Intergovernmental Organization or submit itself to any jurisdiction.
*
* Used extensively for parsing the configuration in the \ref
allpix
::ConfigReader.
* Used extensively for parsing the configuration in the \ref
corryvreckan
::ConfigReader.
*/
/**
...
...
@@ -14,8 +14,8 @@
* @brief Collection of all the overloads of string conversions
*/
#ifndef CORRYVRECKAN_
STRING
_H
#define CORRYVRECKAN_
STRING
_H
#ifndef CORRYVRECKAN_
TEXT
_H
#define CORRYVRECKAN_
TEXT
_H
#include <cctype>
#include <sstream>
...
...
@@ -24,7 +24,6 @@
#include <vector>
#include "type.h"
#include "unit.h"
// TODO [doc]: should possible be put in a separate namespace
...
...
@@ -35,182 +34,69 @@ namespace corryvreckan {
* @param str String that should be trimmed
* @param delims List of delimiters to trim from the string (defaults to all whitespace)
*/
inline
std
::
string
trim
(
const
std
::
string
&
str
,
const
std
::
string
&
delims
=
"
\t\n\r\v
"
)
{
size_t
b
=
str
.
find_first_not_of
(
delims
);
size_t
e
=
str
.
find_last_not_of
(
delims
);
if
(
b
==
std
::
string
::
npos
||
e
==
std
::
string
::
npos
)
{
return
""
;
}
return
std
::
string
(
str
,
b
,
e
-
b
+
1
);
}
std
::
string
trim
(
const
std
::
string
&
str
,
const
std
::
string
&
delims
=
"
\t\n\r\v
"
);
/**
* @brief Converts a string to any supported type
* @param str String to convert
* @see StringConversions
*
* The matching converter function is automatically found if available. To add a new conversion the \ref from_string_impl
* function should be overloaded. The string is passed as first argument to this function, the second argument should be
* an \ref corryvreckan::type_tag with the type to convert to.
*
*/
template
<
typename
T
>
T
from_string
(
std
::
string
str
)
{
// Use tag dispatch to select the correct helper function
return
from_string_impl
(
str
,
type_tag
<
T
>
());
}
// TODO [doc] This should move to a source file
// FIXME: include exceptions better
// helper functions to do cleaning and checks for string reading
static
std
::
string
_from_string_helper
(
std
::
string
str
)
{
// Check if string is not empty
str
=
trim
(
str
);
if
(
str
.
empty
())
{
throw
std
::
invalid_argument
(
"string is empty"
);
}
template
<
typename
T
>
T
from_string
(
std
::
string
str
);
// Check if there is whitespace in the string
size_t
white_space
=
str
.
find_first_of
(
"
\t\n\r\v
"
);
if
(
white_space
!=
std
::
string
::
npos
)
{
throw
std
::
invalid_argument
(
"remaining data at end"
);
}
return
str
;
}
/**
* @brief Internal helper method for checking and trimming conversions from string
* @param str Input string to check and trim
* @return Trimmed string
*/
std
::
string
from_string_helper
(
std
::
string
str
);
/**
* @ingroup StringConversions
* @brief Conversion handler for all non implemented conversions
*
* Function does not return but will raise an static assertion.
* @warning Function does not return but will raise an static assertion.
*/
template
<
typename
T
,
typename
=
std
::
enable_if_t
<!
std
::
is_arithmetic
<
T
>
::
value
>
,
typename
=
void
>
constexpr
T
from_string_impl
(
const
std
::
string
&
,
type_tag
<
T
>
)
{
static_assert
(
std
::
is_same
<
T
,
void
>::
value
,
"Conversion to this type is not implemented: an overload should be added to support this conversion"
);
return
T
();
}
constexpr
T
from_string_impl
(
const
std
::
string
&
,
type_tag
<
T
>
);
/**
* @ingroup StringConversions
* @brief Conversion handler for all arithmetic types
* @throws std::invalid_argument If the string cannot be converted to the required arithmetic type
*
* The unit system is used through \ref Units::get to parse unit suffixes and convert the values to the appropriate
* standard framework unit.
*/
template
<
typename
T
,
typename
=
std
::
enable_if_t
<
std
::
is_arithmetic
<
T
>
::
value
>>
T
from_string_impl
(
std
::
string
str
,
type_tag
<
T
>
)
{
str
=
_from_string_helper
(
str
);
// Find an optional set of units
auto
unit_idx
=
str
.
size
()
-
1
;
for
(;
unit_idx
>
0
;
--
unit_idx
)
{
if
(
!
isalpha
(
str
[
unit_idx
])
&&
str
[
unit_idx
]
!=
'*'
&&
str
[
unit_idx
]
!=
'/'
)
{
break
;
}
}
std
::
string
units
=
str
.
substr
(
unit_idx
+
1
);
// Get the actual arithmetic value
std
::
istringstream
sstream
(
str
.
substr
(
0
,
unit_idx
+
1
));
T
ret_value
=
0
;
sstream
>>
ret_value
;
// Check if the reading was succesfull and everything was read
if
(
sstream
.
fail
()
||
sstream
.
peek
()
!=
EOF
)
{
throw
std
::
invalid_argument
(
"conversion not possible"
);
}
// Apply all the units if they exists
if
(
!
units
.
empty
())
{
ret_value
=
corryvreckan
::
Units
::
get
(
ret_value
,
units
);
}
return
ret_value
;
}
T
from_string_impl
(
std
::
string
str
,
type_tag
<
T
>
);
/**
* @ingroup StringConversions
* @brief Conversion handler for strings
* @throws std::invalid_argument If the string has no closing quotation mark as last character after an opening quotation
* mark
* @throws std::invalid_argument If the string has no enclosing quotation marks but contains more data after whitespace
* is found
*
* If a pair of enclosing double quotation marks is found, the whole string within the quotation marks is returned.
* Otherwise only the first part is read until whitespace is encountered.
* @throws std::invalid_argument If no closing quotation mark as last character after an opening quotation mark
* @throws std::invalid_argument If string without enclosing quotation marks, but more data after whitespace is found
*/
inline
std
::
string
from_string_impl
(
std
::
string
str
,
type_tag
<
std
::
string
>
)
{
str
=
trim
(
str
);
// If there are "" then we should take the whole string
if
(
!
str
.
empty
()
&&
(
str
.
front
()
==
'\"'
||
str
.
front
()
==
'\''
))
{
if
(
str
.
find
(
str
.
front
(),
1
)
!=
str
.
size
()
-
1
)
{
throw
std
::
invalid_argument
(
"remaining data at end"
);
}
return
str
.
substr
(
1
,
str
.
size
()
-
2
);
}
// Otherwise read a single string
return
_from_string_helper
(
str
);
}
std
::
string
from_string_impl
(
std
::
string
str
,
type_tag
<
std
::
string
>
);
/**
* @ingroup StringConversions
* @brief Conversion handler for booleans
* @throws std::invalid_argument If the string cannot be converted to a boolean type
*
* Converts both numerical (0, 1) and textual representations ("false", "true") are supported. No enclosing quotation
* marks should be used.
*/
inline
bool
from_string_impl
(
std
::
string
str
,
type_tag
<
bool
>
)
{
str
=
_from_string_helper
(
str
);
std
::
istringstream
sstream
(
str
);
bool
ret_value
=
false
;
if
(
isalpha
(
str
.
back
())
!=
0
)
{
sstream
>>
std
::
boolalpha
>>
ret_value
;
}
else
{
sstream
>>
ret_value
;
}
// Check if the reading was succesfull and everything was read
if
(
sstream
.
fail
()
||
sstream
.
peek
()
!=
EOF
)
{
throw
std
::
invalid_argument
(
"conversion not possible"
);
}
return
ret_value
;
}
bool
from_string_impl
(
std
::
string
str
,
type_tag
<
bool
>
);
/**
* @brief Converts any type to a string
* @note C-strings are not supported due to allocation issues
*
* The matching converter function is automatically found if available. To add a new conversion the \ref to_string_impl
* function should be overloaded. The string is passed as first argument to this function, the second argument should be
* an \ref corryvreckan::empty_tag (needed to search in the corryvreckan namespace).
*/
template
<
typename
T
>
std
::
string
to_string
(
T
inp
)
{
// Use tag dispatch to select the correct implementation
return
to_string_impl
(
inp
,
empty_tag
());
}
template
<
typename
T
>
std
::
string
to_string
(
T
inp
);
/**
* @ingroup StringConversions
* @brief Conversion handler for all non implemented conversions
*
* Function does not return but will raise an static assertion.
* @warning Function does not return but will raise an static assertion.
*/
template
<
typename
T
,
typename
=
std
::
enable_if_t
<!
std
::
is_arithmetic
<
T
>
::
value
>
,
typename
=
void
>
constexpr
void
to_string_impl
(
T
,
empty_tag
)
{
static_assert
(
std
::
is_same
<
T
,
void
>::
value
,
"Conversion to this type is not implemented: an overload should be added to support this conversion"
);
}
constexpr
void
to_string_impl
(
T
,
empty_tag
);
/**
* @ingroup StringConversions
* @brief Conversion handler for all arithmetic types
*/
template
<
typename
T
,
typename
=
std
::
enable_if_t
<
std
::
is_arithmetic
<
T
>
::
value
>>
std
::
string
to_string_impl
(
T
inp
,
empty_tag
)
{
std
::
ostringstream
out
;
out
<<
inp
;
return
out
.
str
();
}
std
::
string
to_string_impl
(
T
inp
,
empty_tag
);
///@{
/**
...
...
@@ -228,34 +114,13 @@ namespace corryvreckan {
/**
* @brief Splits string into substrings at delimiters
* @param str String to split
* @param delims Delimiters to split at
* @param delims Delimiters to split at
(defaults to space, tab and comma)
* @return List of all the substrings with all empty substrings ignored (thus removed)
*/
template
<
typename
T
>
std
::
vector
<
T
>
split
(
std
::
string
str
,
const
std
::
string
&
delims
=
"
\t
,"
)
{
str
=
trim
(
str
,
delims
);
// If the input string is empty, simply return empty container
if
(
str
.
empty
())
{
return
std
::
vector
<
T
>
();
}
// Else we have data, clear the default elements and chop the string:
std
::
vector
<
T
>
elems
;
// Loop through the string
std
::
size_t
prev
=
0
,
pos
;
while
((
pos
=
str
.
find_first_of
(
delims
,
prev
))
!=
std
::
string
::
npos
)
{
if
(
pos
>
prev
)
{
elems
.
push_back
(
from_string
<
T
>
(
str
.
substr
(
prev
,
pos
-
prev
)));
}
prev
=
pos
+
1
;
}
if
(
prev
<
str
.
length
())
{
elems
.
push_back
(
from_string
<
T
>
(
str
.
substr
(
prev
,
std
::
string
::
npos
)));
}
return
elems
;
}
template
<
typename
T
>
std
::
vector
<
T
>
split
(
std
::
string
str
,
const
std
::
string
&
delims
=
"
\t
,"
);
}
// namespace corryvreckan
#endif
/* CORRYVRECKAN_STRING_H */
// Include template definitions
#include "text.tpp"
#endif
/* CORRYVRECKAN_TEXT_H */
src/core/utils/text.tpp
0 → 100644
View file @
82b93bd4
#include "unit.h"
namespace
corryvreckan
{
/**
* The matching converter function is automatically found if available. To add a new conversion the \ref from_string_impl
* function should be overloaded. The string is passed as first argument to this function, the second argument should be
* an \ref corryvreckan::type_tag with the type to convert to.
*/
template
<
typename
T
>
T
from_string
(
std
::
string
str
)
{
// Use tag dispatch to select the correct helper function
return
from_string_impl
(
str
,
type_tag
<
T
>
());
}
template
<
typename
T
,
typename
>
constexpr
T
from_string_impl
(
const
std
::
string
&
,
type_tag
<
T
>
)
{
static_assert
(
std
::
is_same
<
T
,
void
>::
value
,
"Conversion to this type is not implemented: an overload should be added to support this conversion"
);
return
T
();
}
/**
* The unit system is used through \ref Units::get to parse unit suffixes and convert the values to the appropriate
* standard framework unit.
*/
template
<
typename
T
,
typename
>
T
from_string_impl
(
std
::
string
str
,
type_tag
<
T
>
)
{
str
=
from_string_helper
(
str
);
// Find an optional set of units
auto
unit_idx
=
str
.
size
()
-
1
;
for
(;
unit_idx
>
0
;
--
unit_idx
)
{
if
(
!
isalpha
(
str
[
unit_idx
])
&&
str
[
unit_idx
]
!=
'*'
&&
str
[
unit_idx
]
!=
'/'
)
{
break
;
}
}
std
::
string
units
=
str
.
substr
(
unit_idx
+
1
);
// Get the actual arithmetic value
std
::
istringstream
sstream
(
str
.
substr
(
0
,
unit_idx
+
1
));
T
ret_value
=
0
;
sstream
>>
ret_value
;
// Check if the reading was succesfull and everything was read
if
(
sstream
.
fail
()
||
sstream
.
peek
()
!=
EOF
)
{
throw
std
::
invalid_argument
(
"conversion not possible"
);
}
// Apply all the units if they exists
if
(
!
units
.
empty
())
{
ret_value
=
corryvreckan
::
Units
::
get
(
ret_value
,
units
);
}
return
ret_value
;
}
/**
* The matching converter function is automatically found if available. To add a new conversion the \ref to_string_impl
* function should be overloaded. The string is passed as first argument to this function, the second argument should be
* an \ref corryvreckan::empty_tag (required to search in the corryvreckan namespace).
*/
template
<
typename
T
>
std
::
string
to_string
(
T
inp
)
{
// Use tag dispatch to select the correct implementation
return
to_string_impl
(
inp
,
empty_tag
());
}
template
<
typename
T
,
typename
,
typename
>
constexpr
void
to_string_impl
(
T
,
empty_tag
)
{
static_assert
(
std
::
is_same
<
T
,
void
>::
value
,
"Conversion to this type is not implemented: an overload should be added to support this conversion"
);
}
template
<
typename
T
,
typename
>
std
::
string
to_string_impl
(
T
inp
,
empty_tag
)
{
std
::
ostringstream
out
;
out
<<
inp
;
return
out
.
str
();
}
template
<
typename
T
>
std
::
vector
<
T
>
split
(
std
::
string
str
,
const
std
::
string
&
delims
)
{
str
=
trim
(
str
,
delims
);
// If the input string is empty, simply return empty container
if
(
str
.
empty
())
{
return
std
::
vector
<
T
>
();
}
// Else we have data, clear the default elements and chop the string:
std
::
vector
<
T
>
elems
;
// Loop through the string
std
::
size_t
prev
=
0
,
pos
;
while
((
pos
=
str
.
find_first_of
(
delims
,
prev
))
!=
std
::
string
::
npos
)
{
if
(
pos
>
prev
)
{
elems
.
push_back
(
from_string
<
T
>
(
str
.
substr
(
prev
,
pos
-
prev
)));
}
prev
=
pos
+
1
;
}
if
(
prev
<
str
.
length
())
{
elems
.
push_back
(
from_string
<
T
>
(
str
.
substr
(
prev
,
std
::
string
::
npos
)));
}
return
elems
;
}
}
// namespace corryvreckan
src/core/utils/type.h
View file @
82b93bd4
...
...
@@ -2,10 +2,8 @@
* @file
* @brief Tags for type dispatching and run time type identification
* @copyright Copyright (c) 2017 CERN and the Allpix Squared authors.
* This software is distributed under the terms of the MIT License, copied
* verbatim in the file "LICENSE.md".
* In applying this license, CERN does not waive the privileges and immunities
* granted to it by virtue of its status as an
* This software is distributed under the terms of the MIT License, copied verbatim in the file "LICENSE.md".
* In applying this license, CERN does not waive the privileges and immunities granted to it by virtue of its status as an
* Intergovernmental Organization or submit itself to any jurisdiction.
*/
...
...
@@ -21,14 +19,12 @@
namespace
corryvreckan
{