Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
L
libcifpp
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
open
libcifpp
Commits
0eaeb165
Unverified
Commit
0eaeb165
authored
Jul 27, 2022
by
Maarten L. Hekkelman
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
split out item
parent
f4a6533f
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
588 additions
and
89 deletions
+588
-89
include/cif++/Cif++-v2.hpp
+156
-75
include/cif++/v2/item.hpp
+412
-0
test/unit-v2-test.cpp
+20
-14
No files found.
include/cif++/Cif++-v2.hpp
View file @
0eaeb165
...
...
@@ -35,50 +35,117 @@
#include "cif++/CifUtils.hpp"
namespace
cif_v2
#include "cif++/v2/item.hpp"
namespace
cif
::
v2
{
template
<
typename
Alloc
=
std
::
allocator
<
void
>>
class
item_t
// template <typename Alloc = std::allocator<void>>
// class item
// {
// public:
// item() = default;
// item(std::string_view name, char value)
// : m_name(name)
// , m_value(value)
// {
// }
// #if defined(__cpp_lib_format)
// template <typename T, std::enable_if_t<std::is_floating_point_v<T>, int> = 0>
// item(std::string_view name, const T &value, int precision)
// : m_name(name)
// , m_value(std::format(".{}f", value, precision))
// {
// }
// #endif
// template <typename T, std::enable_if_t<std::is_arithmetic_v<T>, int> = 0>
// item(const std::string_view name, const T &value)
// : m_name(name)
// , m_value(std::to_string(value))
// {
// }
// item(const std::string_view name, const std::string_view value)
// : m_name(name)
// , m_value(value)
// {
// }
// item(const item &rhs) = default;
// item(item &&rhs) noexcept = default;
// item &operator=(const item &rhs) = default;
// item &operator=(item &&rhs) noexcept = default;
// const std::string &name() const { return m_name; }
// const std::string &value() const { return m_value; }
// void value(const std::string &v) { m_value = v; }
// /// \brief empty means either null or unknown
// bool empty() const { return m_value.empty(); }
// /// \brief returns true if the field contains '.'
// bool is_null() const { return m_value == "."; }
// /// \brief returns true if the field contains '?'
// bool is_unknown() const { return m_value == "?"; }
// size_t length() const { return m_value.length(); }
// const char *c_str() const { return m_value.c_str(); }
// private:
// std::string m_name;
// std::string m_value;
// };
// using item = item<>;
class
item
{
public
:
item
_t
()
=
default
;
item
()
=
default
;
item
_t
(
std
::
string_view
name
,
char
value
)
item
(
std
::
string_view
name
,
char
value
)
:
m_name
(
name
)
,
m_value
(
value
)
,
m_value
(
{
value
}
)
{
}
#if defined(__cpp_lib_format)
template
<
typename
T
,
std
::
enable_if_t
<
std
::
is_floating_point_v
<
T
>
,
int
>
=
0
>
item
_t
(
std
::
string_view
name
,
const
T
&
value
,
int
precision
)
item
(
std
::
string_view
name
,
const
T
&
value
,
int
precision
)
:
m_name
(
name
)
#if defined(__cpp_lib_format)
,
m_value
(
std
::
format
(
".{}f"
,
value
,
precision
))
#endif
{
}
#endif
template
<
typename
T
,
std
::
enable_if_t
<
std
::
is_arithmetic_v
<
T
>
,
int
>
=
0
>
item
_t
(
const
std
::
string_view
name
,
const
T
&
value
)
item
(
const
std
::
string_view
name
,
const
T
&
value
)
:
m_name
(
name
)
,
m_value
(
std
::
to_string
(
value
))
{
}
item
_t
(
const
std
::
string_view
name
,
const
std
::
string_view
value
)
item
(
const
std
::
string_view
name
,
const
std
::
string_view
value
)
:
m_name
(
name
)
,
m_value
(
value
)
{
}
item
_t
(
const
item_t
&
rhs
)
=
default
;
item
(
const
item
&
rhs
)
=
default
;
item
_t
(
item_t
&&
rhs
)
noexcept
=
default
;
item
(
item
&&
rhs
)
noexcept
=
default
;
item
_t
&
operator
=
(
const
item_t
&
rhs
)
=
default
;
item
&
operator
=
(
const
item
&
rhs
)
=
default
;
item
_t
&
operator
=
(
item_t
&&
rhs
)
noexcept
=
default
;
item
&
operator
=
(
item
&&
rhs
)
noexcept
=
default
;
const
std
::
string
&
name
()
const
{
return
m_name
;
}
const
std
::
string
&
value
()
const
{
return
m_value
;
}
...
...
@@ -102,99 +169,113 @@ class item_t
std
::
string
m_value
;
};
using
item
=
item_t
<>
;
// --------------------------------------------------------------------
// template <
// typename Item = item,
// typename Alloc = std::allocator<Item>>
// class row_t : public std::list<Item, Alloc>
// {
// public:
// using value_type = Item;
// using base_type = std::list<Item, Alloc>;
// using allocator_type = Alloc;
template
<
typename
Alloc
=
std
::
allocator
<
std
::
byte
>>
class
row_t
{
using
byte_allocator_type
=
typename
std
::
allocator_traits
<
Alloc
>::
template
rebind_alloc
<
std
::
byte
>
;
// row_t() = default;
struct
AllocTraitsImpl
:
std
::
allocator_traits
<
byte_allocator_type
>
{
using
base_type
=
std
::
allocator_traits
<
byte_allocator_type
>
;
// row_t(const std::string &name, const allocator_type &alloc = allocator_type())
// : base_type(alloc)
// , m_name(name) {}
static
constexpr
typename
base_type
::
pointer
allocate
(
byte_allocator_type
&
a
,
typename
base_type
::
size_type
n
)
{
return
base_type
::
allocate
(
a
,
n
);
}
};
// row_t(const row_t &) = default;
// row_t(row_t &&) = default
;
using
AllocTraits
=
AllocTraitsImpl
;
// template<typename Alloc2>
// row_t(const row_t &r, const Alloc2 &a)
// : base_type(r, a)
// , m_name(r.m_name)
// {
// }
public
:
// template<typename Alloc2>
// row_t(row_t &&r, const Alloc2 &a)
// : base_type(std::move(r), a)
// , m_name(r.m_name)
// {
// }
using
allocator_type
=
byte_allocator_type
;
// row_t &operator=(const row_t &) = default;
// row_t &operator=(row_t &&) = default;
row_t
(
const
allocator_type
&
alloc
=
allocator_type
())
:
m_allocator
(
alloc
)
{}
// row_t(std::initializer_list<item_type> items, const allocator_type &alloc = allocator_type())
// {
row_t
(
const
row_t
&
)
=
default
;
// }
row_t
(
row_t
&&
)
=
default
;
// // --------------------------------------------------------------------
// template<typename Alloc2>
// row_t(const row_t &r, const Alloc2 &a)
// : m_allocator(a)
// {
// }
// const std::string &name() const { return m_name; }
// const std::string &value() const { return m_value; }
// template<typename Alloc2>
// row_t(row_t &&r, const Alloc2 &a)
// : m_allocator(a)
// {
// }
// private:
// std::string m_name;
// std::string m_value;
// };
row_t
&
operator
=
(
const
row_t
&
)
=
default
;
row_t
&
operator
=
(
row_t
&&
)
=
default
;
// using row = row_t<>;
row_t
(
std
::
initializer_list
<
item
>
items
,
const
allocator_type
&
alloc
=
allocator_type
())
:
m_allocator
(
alloc
)
{
// --------------------------------------------------------------------
}
namespace
detail
{
item_handle
<
row_t
>
operator
[](
uint32_t
column_ix
)
{
return
item_handle
<
row_t
>
(
column_ix
,
*
this
);
}
struct
item_value
{
item_value
*
m_next
;
uint32_t
m_column_ix
;
char
m_text
[
4
];
};
const
item_handle
<
const
row_t
>
operator
[](
uint32_t
column_ix
)
const
{
return
item_handle
<
const
row_t
>
(
column_ix
,
*
this
);
}
item_handle
<
row_t
>
operator
[](
std
::
string_view
column_name
)
{
return
item_handle
<
row_t
>
(
column_name
,
get_column_ix
(
column_name
),
*
this
);
}
}
const
item_handle
<
const
row_t
>
operator
[](
std
::
string_view
column_name
)
const
{
return
item_handle
<
const
row_t
>
(
column_name
,
get_column_ix
(
column_name
),
*
this
);
}
// --------------------------------------------------------------------
// --------------------------------------------------------------------
private
:
uint32_t
get_column_ix
(
std
::
string_view
name
)
const
{
return
0
;
}
template
<
typename
R
>
friend
class
item_handle
;
allocator_type
m_allocator
;
item_value
*
m_head
=
nullptr
,
*
m_tail
=
nullptr
;
size_t
m_size
=
0
;
};
template
<
typename
Item
=
item
,
typename
Alloc
=
std
::
allocator
<
Item
>>
using
row
=
std
::
forward_list
<
Item
,
Alloc
>
;
using
row
=
row_t
<>
;
// --------------------------------------------------------------------
template
<
typename
Row
=
row
,
typename
Alloc
=
std
::
allocator
<
std
::
byte
>>
class
category_t
class
category_t
:
public
std
::
forward_list
<
Row
,
std
::
scoped_allocator_adaptor
<
std
::
allocator
<
Row
>>>
{
public
:
using
item_type
=
Item
;
using
value_type
=
Row
;
using
base_type
=
std
::
list
<
Row
,
Alloc
>
;
using
base_type
=
std
::
forward_list
<
Row
,
std
::
scoped_allocator_adaptor
<
std
::
allocator
<
Row
>>
>
;
using
allocator_type
=
Alloc
;
category_t
()
=
default
;
...
...
@@ -232,9 +313,9 @@ class category_t
void
emplace
(
value_type
&&
row
);
void
emplace
(
std
::
initializer_list
<
item
_type
>
items
)
void
emplace
(
std
::
initializer_list
<
item
>
items
)
{
this
->
emplace_back
(
value_type
{
items
});
this
->
emplace_back
(
value_type
{
items
,
this
->
get_allocator
()
});
}
// void write(std::ostream &os, const std::vector<size_t> &order, bool includeEmptyColumns)
...
...
@@ -424,7 +505,7 @@ class category_t
};
std
::
string
m_name
;
std
::
vector
<
item_column
>
m_columns
;
std
::
vector
<
item_column
,
typename
std
::
allocator_traits
<
allocator_type
>::
template
rebind_alloc
<
item_column
>
>
m_columns
;
};
using
category
=
category_t
<>
;
...
...
include/cif++/v2/item.hpp
0 → 100644
View file @
0eaeb165
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2022 NKI/AVL, Netherlands Cancer Institute
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include <cstring>
#include <memory>
#include <optional>
namespace
cif
::
v2
{
// --------------------------------------------------------------------
// Internal storage, strictly forward linked list with minimal space
// requirements.
struct
item_value
{
item_value
(
uint32_t
column_ix
,
const
char
*
value
)
:
m_column_ix
(
column_ix
)
{
strcpy
(
m_text
,
value
);
}
~
item_value
()
{
// remove recursively (and be paranoid)
while
(
m_next
!=
nullptr
and
m_next
!=
this
)
{
auto
n
=
m_next
;
m_next
=
n
->
m_next
;
n
->
m_next
=
nullptr
;
delete
n
;
}
}
item_value
*
m_next
;
uint32_t
m_column_ix
;
char
m_text
[
4
];
};
// --------------------------------------------------------------------
// Transient object to access stored data
template
<
typename
Row
>
struct
item_handle
{
using
row_type
=
Row
;
public
:
// conversion helper class
template
<
typename
T
,
typename
=
void
>
struct
item_value_as
;
template
<
typename
T
,
std
::
enable_if_t
<
std
::
is_arithmetic_v
<
T
>
,
int
>
=
0
>
item_handle
&
operator
=
(
const
T
&
value
)
{
this
->
operator
=
(
std
::
to_string
(
value
));
return
*
this
;
}
template
<
typename
T
>
item_handle
&
operator
=
(
const
std
::
optional
<
T
>
&
value
)
{
if
(
value
)
this
->
operator
=
(
*
value
);
else
this
->
operator
=
(
"?"
);
return
*
this
;
}
item_handle
&
operator
=
(
const
std
::
string
&
value
)
{
m_row
.
assign
(
m_name
,
value
,
false
);
return
*
this
;
}
template
<
typename
...
Ts
>
void
os
(
const
Ts
&
...
v
)
{
std
::
ostringstream
ss
;
((
ss
<<
v
),
...);
this
->
operator
=
(
ss
.
str
());
}
void
swap
(
item_handle
&
b
);
template
<
typename
T
=
std
::
string
>
auto
as
()
const
{
using
value_type
=
std
::
remove_cv_t
<
std
::
remove_reference_t
<
T
>>
;
return
item_value_as
<
value_type
>::
convert
(
*
this
);
}
template
<
typename
T
>
auto
value_or
(
const
T
&
dv
)
{
return
empty
()
?
dv
:
this
->
as
<
T
>
();
}
template
<
typename
T
>
int
compare
(
const
T
&
value
,
bool
icase
)
const
{
return
item_value_as
<
T
>::
compare
(
*
this
,
value
,
icase
);
}
// empty means either null or unknown
bool
empty
()
const
{
const
char
*
s
=
c_str
();
return
*
s
==
0
or
(
s
[
1
]
==
0
and
(
*
s
==
'.'
or
*
s
==
'?'
));
}
explicit
operator
bool
()
const
{
return
not
empty
();
}
// is_null means the field contains '.'
bool
is_null
()
const
{
const
char
*
s
=
c_str
();
return
*
s
==
'.'
and
s
[
1
]
==
0
;
}
// is_unknown means the field contains '?'
bool
is_unknown
()
const
{
const
char
*
s
=
c_str
();
return
*
s
==
'?'
and
s
[
1
]
==
0
;
}
const
char
*
c_str
()
const
{
for
(
auto
iv
=
m_row
.
m_head
;
iv
!=
nullptr
;
iv
=
iv
->
m_next
)
{
if
(
iv
->
m_column_ix
==
m_column
)
return
iv
->
m_text
;
}
return
s_empty_result
;
}
// bool operator!=(const std::string &s) const { return s != c_str(); }
// bool operator==(const std::string &s) const { return s == c_str(); }
item_handle
(
std
::
string_view
name
,
size_t
column
,
row_type
&
row
)
:
m_name
(
name
)
,
m_column
(
column
)
,
m_row
(
row
)
{
}
item_handle
(
std
::
string_view
name
,
size_t
column
,
const
row_type
&
row
)
:
m_name
(
name
)
,
m_column
(
column
)
,
m_row
(
const_cast
<
row_type
&>
(
row
))
// , mConst(true)
{
}
private
:
std
::
string_view
m_name
;
size_t
m_column
;
row_type
&
m_row
;
// bool mConst = false;
static
constexpr
const
char
*
s_empty_result
=
""
;
};
template
<
typename
Row
>
template
<
typename
T
>
struct
item_handle
<
Row
>::
item_value_as
<
T
,
std
::
enable_if_t
<
std
::
is_floating_point_v
<
T
>>>
{
using
value_type
=
std
::
remove_reference_t
<
std
::
remove_cv_t
<
T
>>
;
static
value_type
convert
(
const
item_handle
&
ref
)
{
value_type
result
=
{};
if
(
not
ref
.
empty
())
result
=
static_cast
<
value_type
>
(
std
::
stod
(
ref
.
c_str
()));
return
result
;
}
static
int
compare
(
const
item_handle
&
ref
,
double
value
,
bool
icase
)
{
int
result
=
0
;
const
char
*
s
=
ref
.
c_str
();
if
(
s
==
nullptr
or
*
s
==
0
)
result
=
1
;
else
{
try
{
auto
v
=
std
::
strtod
(
s
,
nullptr
);
if
(
v
<
value
)
result
=
-
1
;
else
if
(
v
>
value
)
result
=
1
;
}
catch
(...)
{
// if (VERBOSE)
// std::cerr << "conversion error in compare for '" << ref.c_str() << '\'' << std::endl;
result
=
1
;
}
}
return
result
;
}
};
template
<
typename
Row
>
template
<
typename
T
>
struct
item_handle
<
Row
>::
item_value_as
<
T
,
std
::
enable_if_t
<
std
::
is_integral_v
<
T
>
and
std
::
is_unsigned_v
<
T
>
and
not
std
::
is_same_v
<
T
,
bool
>>>
{
static
T
convert
(
const
item_handle
&
ref
)
{
T
result
=
{};
if
(
not
ref
.
empty
())
result
=
static_cast
<
T
>
(
std
::
stoul
(
ref
.
c_str
()));
return
result
;
}
static
int
compare
(
const
item_handle
&
ref
,
unsigned
long
value
,
bool
icase
)
{
int
result
=
0
;
const
char
*
s
=
ref
.
c_str
();
if
(
s
==
nullptr
or
*
s
==
0
)
result
=
1
;
else
{
try
{
auto
v
=
std
::
strtoul
(
s
,
nullptr
,
10
);
if
(
v
<
value
)
result
=
-
1
;
else
if
(
v
>
value
)
result
=
1
;
}
catch
(...)
{
// if (VERBOSE)
// std::cerr << "conversion error in compare for '" << ref.c_str() << '\'' << std::endl;
result
=
1
;
}
}
return
result
;
}
};
template
<
typename
Row
>
template
<
typename
T
>
struct
item_handle
<
Row
>::
item_value_as
<
T
,
std
::
enable_if_t
<
std
::
is_integral_v
<
T
>
and
std
::
is_signed_v
<
T
>
and
not
std
::
is_same_v
<
T
,
bool
>>>
{
static
T
convert
(
const
item_handle
&
ref
)
{
T
result
=
{};
if
(
not
ref
.
empty
())
result
=
static_cast
<
T
>
(
std
::
stol
(
ref
.
c_str
()));
return
result
;
}
static
int
compare
(
const
item_handle
&
ref
,
long
value
,
bool
icase
)
{
int
result
=
0
;
const
char
*
s
=
ref
.
c_str
();
if
(
s
==
nullptr
or
*
s
==
0
)
result
=
1
;
else
{
try
{
auto
v
=
std
::
strtol
(
s
,
nullptr
,
10
);
if
(
v
<
value
)
result
=
-
1
;
else
if
(
v
>
value
)
result
=
1
;
}
catch
(...)
{
// if (VERBOSE)
// std::cerr << "conversion error in compare for '" << ref.c_str() << '\'' << std::endl;
result
=
1
;
}
}
return
result
;
}
};
template
<
typename
Row
>
template
<
typename
T
>
struct
item_handle
<
Row
>::
item_value_as
<
std
::
optional
<
T
>>
{
static
std
::
optional
<
T
>
convert
(
const
item_handle
&
ref
)
{
std
::
optional
<
T
>
result
;
if
(
ref
)
result
=
ref
.
as
<
T
>
();
return
result
;
}
static
int
compare
(
const
item_handle
&
ref
,
std
::
optional
<
T
>
value
,
bool
icase
)
{
if
(
ref
.
empty
()
and
not
value
)
return
0
;
if
(
ref
.
empty
())
return
-
1
;
else
if
(
not
value
)
return
1
;
else
return
ref
.
compare
(
*
value
,
icase
);
}
};
template
<
typename
Row
>
template
<
typename
T
>
struct
item_handle
<
Row
>::
item_value_as
<
T
,
std
::
enable_if_t
<
std
::
is_same_v
<
T
,
bool
>>>
{
static
bool
convert
(
const
item_handle
&
ref
)
{
bool
result
=
false
;
if
(
not
ref
.
empty
())
result
=
iequals
(
ref
.
c_str
(),
"y"
);
return
result
;
}
static
int
compare
(
const
item_handle
&
ref
,
bool
value
,
bool
icase
)
{
bool
rv
=
convert
(
ref
);
return
value
&&
rv
?
0
:
(
rv
<
value
?
-
1
:
1
);
}
};
template
<
typename
Row
>
template
<
size_t
N
>
struct
item_handle
<
Row
>::
item_value_as
<
char
[
N
]
>
{
static
const
char
*
convert
(
const
item_handle
&
ref
)
{
return
ref
.
c_str
();
}
static
int
compare
(
const
item_handle
&
ref
,
const
char
(
&
value
)[
N
],
bool
icase
)
{
return
icase
?
cif
::
icompare
(
ref
.
c_str
(),
value
)
:
std
::
strcmp
(
ref
.
c_str
(),
value
);
}
};
template
<
typename
Row
>
template
<
typename
T
>
struct
item_handle
<
Row
>::
item_value_as
<
T
,
std
::
enable_if_t
<
std
::
is_same_v
<
T
,
const
char
*>>>
{
static
const
char
*
convert
(
const
item_handle
&
ref
)
{
return
ref
.
c_str
();
}
static
int
compare
(
const
item_handle
&
ref
,
const
char
*
value
,
bool
icase
)
{
return
icase
?
cif
::
icompare
(
ref
.
c_str
(),
value
)
:
std
::
strcmp
(
ref
.
c_str
(),
value
);
}
};
template
<
typename
Row
>
template
<
typename
T
>
struct
item_handle
<
Row
>::
item_value_as
<
T
,
std
::
enable_if_t
<
std
::
is_same_v
<
T
,
std
::
string
>>>
{
static
std
::
string
convert
(
const
item_handle
&
ref
)
{
return
ref
.
c_str
();
}
static
int
compare
(
const
item_handle
&
ref
,
const
std
::
string
&
value
,
bool
icase
)
{
return
icase
?
cif
::
icompare
(
ref
.
c_str
(),
value
)
:
std
::
strcmp
(
ref
.
c_str
(),
value
.
c_str
());
}
};
}
// namespace cif::v2
test/unit-v2-test.cpp
View file @
0eaeb165
...
...
@@ -41,7 +41,7 @@ std::filesystem::path gTestDir = std::filesystem::current_path(); // filled in f
// --------------------------------------------------------------------
cif
_
v2
::
file
operator
""
_cf
(
const
char
*
text
,
size_t
length
)
cif
::
v2
::
file
operator
""
_cf
(
const
char
*
text
,
size_t
length
)
{
struct
membuf
:
public
std
::
streambuf
{
...
...
@@ -52,7 +52,7 @@ cif_v2::file operator""_cf(const char *text, size_t length)
}
buffer
(
const_cast
<
char
*>
(
text
),
length
);
std
::
istream
is
(
&
buffer
);
return
cif
_
v2
::
file
(
is
);
return
cif
::
v2
::
file
(
is
);
}
// --------------------------------------------------------------------
...
...
@@ -78,18 +78,24 @@ bool init_unit_test()
BOOST_AUTO_TEST_CASE
(
r_1
)
{
cif_v2
::
category
c
(
"foo"
);
c
.
emplace
({
{
"f-1"
,
1
},
{
"f-2"
,
"two"
},
{
"f-3"
,
3.0
},
// { "f-4", 3.0, 3 }
});
cif_v2
::
datablock
db
(
"test"
);
db
.
emplace_back
(
std
::
move
(
c
));
std
::
cout
<<
db
<<
std
::
endl
;
cif
::
v2
::
row
r
;
std
::
cout
<<
r
[
"f1"
].
value_or
(
"<leeg>"
)
<<
std
::
endl
;
// cif::v2::category c("foo");
// c.emplace({
// { "f-1", 1 },
// { "f-2", "two" },
// { "f-3", 3.0 },
// // { "f-4", 3.0, 3 }
// });
// cif::v2::datablock db("test");
// db.emplace_back(std::move(c));
// std::cout << db << std::endl;
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment