Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F376114
CSVWriter.hpp
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Size
7 KB
Referenced Files
None
Subscribers
None
CSVWriter.hpp
View Options
//===-- rosa/support/csv/CSVWriter.hpp --------------------------*- C++ -*-===//
//
// The RoSA Framework
//
// Distributed under the terms and conditions of the Boost Software License 1.0.
// See accompanying file LICENSE.
//
// If you did not receive a copy of the license file, see
// http://www.boost.org/LICENSE_1_0.txt.
//
//===----------------------------------------------------------------------===//
///
/// \file rosa/support/csv/CSVWriter.hpp
///
/// \authors David Juhasz (david.juhasz@tuwien.ac.at)
/// Edwin Willegger (edwin.willegger@tuwien.ac.at)
///
/// \date 2017-2019
///
/// \brief Facitilities to write CSV files.
///
//===----------------------------------------------------------------------===//
#ifndef ROSA_SUPPORT_CSV_CSVWRITER_HPP
#define ROSA_SUPPORT_CSV_CSVWRITER_HPP
#include
<iostream>
#include
<ostream>
#include
<array>
#include
<tuple>
#include
<vector>
#include
"rosa/support/log.h"
namespace
rosa
{
namespace
csv
{
/// Provides facilities to write values into a CSV file.
///
/// The writer emits a comma, the character `,`, between each written values.
/// The resulted stream is a flat CSV file as it consists of onlyone row, no new
/// line is emitted.
///
/// \tparam T type of values to write
template
<
typename
T
>
class
CSVWriter
{
public
:
/// Creates a new instance.
///
/// \param [in,out] S output stream to write to
///
/// \note The writer operates on non-binary outputs as long as \p S is in
/// good state.
CSVWriter
(
std
::
ostream
&
S
)
:
Str
(
S
.
good
()
&&
!
(
S
.
flags
()
&
std
::
ios
::
binary
)
?
&
S
:
nullptr
),
IsFirst
(
true
)
{}
/// Tells if the last operation was successful.
///
/// \return if the last operation was successful
bool
good
(
void
)
const
noexcept
{
return
Str
!=
nullptr
;
}
/// Writes an entry to the output stream.
///
/// The implementation does anything only if the last operation was
/// successful. If so, \p V is written to \c rosa::csv::CSVWriter::Str.
/// The emitted value is preceded with a comma if the actual call is not the
/// first one for \p this object. Success of the operation is checked at the
/// end.
///
/// \param V value to write
void
write
(
const
T
&
V
)
{
if
(
Str
)
{
if
(
!
IsFirst
)
{
*
Str
<<
','
;
}
else
{
IsFirst
=
false
;
}
*
Str
<<
V
;
if
(
!
Str
->
good
())
{
Str
=
nullptr
;
}
}
}
private
:
std
::
ostream
*
Str
;
///< Output stream to write to.
bool
IsFirst
;
///< Denotes if the next write would be the first one.
};
/// Writes a tuple of values into a CSV file
///
/// \tparam Ts types of values to write
template
<
typename
...
Ts
>
class
CSVTupleWriter
{
public
:
// typedef <Ts...> value_type ; ///< Type of values written.
typedef
std
::
tuple
<
Ts
...
>
value_type
;
/// Creates a new instance.
///
/// \param [in,out] S output stream to write to
///
/// \note The writer operates on non-binary outputs as long as \p S is in
/// good state.
CSVTupleWriter
(
std
::
ostream
&
S
)
:
Str
(
S
.
good
()
&&
!
(
S
.
flags
()
&
std
::
ios
::
binary
)
?
&
S
:
nullptr
),
IsHeaderWritten
(
false
),
IsDataWritten
(
false
)
{}
/// Tells if the last operation was successful.
///
/// \return if the last operation was successful
bool
good
(
void
)
const
noexcept
{
return
Str
!=
nullptr
;
}
/// Write the values of a tuple to a CSV file with \c
/// rosa::csv::CSVTupleWriter.
///
/// \see rosa::csv::CSVTupleWriter
///
///
/// \param [in,out] values tuple, which values are written in a recusive
/// fashion into a stream.
template
<
size_t
i
=
0
>
void
write
(
const
std
::
tuple
<
Ts
...
>
&
values
)
{
constexpr
size_t
size
=
sizeof
...(
Ts
);
LOG_TRACE_STREAM
<<
"Writing tuple values into file
\n
"
;
LOG_TRACE_STREAM
<<
" Tuple has "
<<
std
::
to_string
(
size
)
<<
" elements.
\n
"
;
LOG_TRACE_STREAM
<<
" Value is "
<<
std
::
get
<
i
>
(
values
);
if
(
Str
)
{
/// Write the current element of the tuple into the stream and add a
/// separtor after it, and call the function for the next element in the
/// tuple.
if
constexpr
(
i
+
1
!=
sizeof
...(
Ts
))
{
*
Str
<<
std
::
get
<
i
>
(
values
)
<<
", "
;
write
<
i
+
1
>
(
values
);
/// If the last element is written into the stream than begin a new
/// line.
}
else
if
constexpr
(
i
+
1
==
sizeof
...(
Ts
))
{
*
Str
<<
std
::
get
<
i
>
(
values
)
<<
'\n'
;
/// every time the last data value of a line is written, the flag
/// indicates that data was already written into the file.
IsDataWritten
=
true
;
}
}
}
/// Write the header values to a CSV file with \c rosa::csv::CSVTupleWriter.
///
/// \note The function has no effect if anything has already been written
/// to the output stream either by \c
/// rosa::csv::CSVTupleWriter::writeHeader() or \c
/// rosa::csv::CSVTupleWriter::write().
///
/// \see rosa::csv::CSVTupleWriter
///
/// \param header the content of the header line.
void
writeHeader
(
const
std
::
array
<
std
::
string
,
sizeof
...(
Ts
)
>
&
header
)
{
size_t
index
=
0
;
/// write into the stream only, if it is not a nullptr, and if no data and
/// no header was already written into it.
if
(
Str
&&
IsDataWritten
==
false
&&
IsHeaderWritten
==
false
)
{
index
=
0
;
for
(
auto
i
=
header
.
begin
();
i
!=
header
.
end
();
++
i
)
{
index
=
index
+
1
;
/// write into the stream every entry with a delimiter, in this case ",
/// " until the last entry
if
(
index
!=
header
.
size
())
{
*
Str
<<
*
i
<<
", "
;
/// write the last entry into the stream, without any delimiter
}
else
{
*
Str
<<
*
i
;
}
}
/// finish the header line and start a new line.
*
Str
<<
'\n'
;
/// now it is not possible to write additional header lines.
IsHeaderWritten
=
true
;
}
}
private
:
std
::
ostream
*
Str
;
///< Output stream to write to.
bool
IsHeaderWritten
;
///< If an header line was already written into the
///< stream. If set than no additional header could be
///< written.
bool
IsDataWritten
;
///< If one line of data has already been written into the
///< stream, than no headerline could be added.
};
/// Writes all values of a tuple to a CSV file with \c
/// rosa::csv::CSVTupleWriter.
///
/// \see rosa::csv::CSVTupleWriter
///
/// \tparam Ts types of values to write
///
/// \param [in,out] W object to write with
/// \param V values to write
///
/// \return \p W after writing \p V with it
template
<
typename
...
Ts
>
CSVTupleWriter
<
Ts
...
>
&
operator
<<
(
CSVTupleWriter
<
Ts
...
>
&
W
,
const
std
::
tuple
<
Ts
...
>
&
V
)
{
W
.
write
(
V
);
return
W
;
}
/// Writes a value to a CSV file with \c rosa::csv::CSVWriter.
///
/// \see rosa::csv::CSVWriter
///
/// \tparam T type of value to write
///
/// \param [in,out] W object to write with
/// \param V value to write
///
/// \return \p W after writing \p V with it
template
<
typename
T
>
CSVWriter
<
T
>
&
operator
<<
(
CSVWriter
<
T
>
&
W
,
const
T
&
V
)
{
W
.
write
(
V
);
return
W
;
}
}
// End namespace csv
}
// End namespace rosa
#endif
// ROSA_SUPPORT_CSV_CSVWRITER_HPP
File Metadata
Details
Attached
Mime Type
text/x-c++
Expires
Sun, Jun 8, 6:58 PM (1 d, 9 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
150501
Default Alt Text
CSVWriter.hpp (7 KB)
Attached To
Mode
R20 SoC_Rosa_repo
Attached
Detach File
Event Timeline
Log In to Comment