Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
C
caosdb-cpplib
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Iterations
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Issue analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
caosdb
Software
caosdb-cpplib
Commits
31ad2cf0
Verified
Commit
31ad2cf0
authored
3 years ago
by
Timm Fitschen
Browse files
Options
Downloads
Patches
Plain Diff
WIP: AbstractValue base class
parent
bfdfc55e
No related branches found
No related tags found
1 merge request
!24
API: Introduce value and datatype structs to Extern C
Pipeline
#13550
failed
3 years ago
Stage: info
Stage: setup
Stage: test
Stage: deploy
Changes
2
Pipelines
1
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
include/caosdb/value.h
+239
-25
239 additions, 25 deletions
include/caosdb/value.h
src/ccaosdb.cpp
+2
-1
2 additions, 1 deletion
src/ccaosdb.cpp
with
241 additions
and
26 deletions
include/caosdb/value.h
+
239
−
25
View file @
31ad2cf0
...
...
@@ -25,6 +25,7 @@
#include
"caosdb/entity/v1alpha1/main.pb.h"
// for RepeatedPtrField, Message
#include
"caosdb/logging.h"
#include
<google/protobuf/util/json_util.h>
// for MessageToJson...
#include
<map>
#include
<memory>
// for unique_ptr
#include
<string>
// for string
#include
<vector>
// for vector
...
...
@@ -37,7 +38,9 @@
}
namespace
caosdb
::
entity
{
using
caosdb
::
utility
::
get_arena
;
using
caosdb
::
utility
::
ProtoMessageWrapper
;
using
google
::
protobuf
::
Arena
;
using
ProtoSpecialValue
=
caosdb
::
entity
::
v1alpha1
::
SpecialValue
;
using
ProtoValue
=
caosdb
::
entity
::
v1alpha1
::
Value
;
using
ProtoScalarValue
=
caosdb
::
entity
::
v1alpha1
::
ScalarValue
;
...
...
@@ -46,6 +49,8 @@ using ScalarValueCase = caosdb::entity::v1alpha1::ScalarValue::ScalarValueCase;
class
Entity
;
class
Property
;
class
ScalarValue
;
class
Value
;
// Represents special values which are otherwise hard to tranfer via protobuf.
enum
SpecialValue
{
...
...
@@ -55,46 +60,225 @@ enum SpecialValue {
EMPTY_STRING
=
ProtoSpecialValue
::
SPECIAL_VALUE_EMPTY_STRING
,
};
class
ScalarValue
:
public
ProtoMessageWrapper
<
ProtoScalar
Value
>
{
class
Abstract
Value
{
public:
/**
* Virtual destructor.
*/
virtual
~
AbstractValue
(){};
/**
* Return true iff the value is a NULL value (NULL in the CaosDB sense).
*/
[[
nodiscard
]]
virtual
auto
IsNull
()
const
noexcept
->
bool
=
0
;
/**
* Return true iff the value is best represented in C++ types as a
* std::string.
*
* If true, clients may call GetAsString to receive a std::string
* representation of the value.
*/
[[
nodiscard
]]
virtual
auto
IsString
()
const
noexcept
->
bool
=
0
;
/**
* Return true iff the value is best represented in C++ types as a
* bool.
*
* If true, clients may call GetAsBool to receive a bool
* representation of the value.
*/
[[
nodiscard
]]
virtual
auto
IsBool
()
const
noexcept
->
bool
=
0
;
/**
* Return true iff the value is best represented in C++ types as a
* double.
*
* If true, clients may call GetAsDouble to receive a double
* representation of the value.
*/
[[
nodiscard
]]
virtual
auto
IsDouble
()
const
noexcept
->
bool
=
0
;
/**
* Return true iff the value is best represented in C++ types as an
* int64_t.
*
* If true, clients may call GetAsInt64 to receive an int64_t
* representation of the value.
*/
[[
nodiscard
]]
virtual
auto
IsInt64
()
const
noexcept
->
bool
=
0
;
/**
* Return true iff the value is best represented in C++ types as a
* std::vector<ScalarValue>.
*
* If true, clients may call GetAsVector to receive a
* std::vector<ScalarValue> representation of the value.
*/
[[
nodiscard
]]
virtual
auto
IsVector
()
const
noexcept
->
bool
=
0
;
/**
* Return a std::string representation of this value.
*
* Clients should call IsString before calling this function in order to
* assure that this value is indeed best represented by a std::string.
*
* The return value is undefined if IsString is false.
*/
[[
nodiscard
]]
virtual
auto
GetAsString
()
const
noexcept
->
const
std
::
string
&
=
0
;
/**
* Return a bool representation of this value.
*
* Clients should call IsBool before calling this function in order to
* assure that this value is indeed best represented by a bool.
*
* The return value is undefined if IsBool is false.
*/
[[
nodiscard
]]
virtual
auto
GetAsBool
()
const
noexcept
->
bool
=
0
;
/**
* Return a double representation of this value.
*
* Clients should call IsDouble before calling this function in order to
* assure that this value is indeed best represented by a double.
*
* The return value is undefined if IsDouble is false.
*/
[[
nodiscard
]]
virtual
auto
GetAsDouble
()
const
noexcept
->
double
=
0
;
/**
* Return an int64_t representation of this value.
*
* Clients should call IsInt64 before calling this function in order to
* assure that this value is indeed best represented by an int64_t.
*
* The return value is undefined if IsInt64 is false.
*/
[[
nodiscard
]]
virtual
auto
GetAsInt64
()
const
noexcept
->
int64_t
=
0
;
/**
* Return a std::vector<ScalarValue> representation of this value.
*
* Clients should call IsVector before calling this function in order to
* assure that this value is indeed best represented by a
* std::vector<ScalarValue>.
*
* The return value is undefined if IsVector is false.
*/
[[
nodiscard
]]
virtual
auto
GetAsVector
()
const
noexcept
->
const
std
::
vector
<
ScalarValue
>
&
=
0
;
friend
class
Value
;
protected
:
[[
nodiscard
]]
virtual
auto
GetProtoValue
()
const
noexcept
->
const
ProtoValue
*
=
0
;
};
class
ScalarValue
:
public
AbstractValue
,
public
ProtoMessageWrapper
<
ProtoScalarValue
>
{
public:
/**
* Destructor.
*/
inline
~
ScalarValue
(){};
/**
* Copy constructor.
*/
inline
ScalarValue
(
const
ScalarValue
&
original
)
:
ScalarValue
()
{
this
->
wrapped
->
CopyFrom
(
*
original
.
wrapped
);
}
/**
* Move constructor.
*/
inline
ScalarValue
(
ScalarValue
&&
other
)
:
ScalarValue
(
std
::
move
(
other
.
wrapped
)){};
/**
* Copy assignment operator.
*/
inline
auto
operator
=
(
const
ScalarValue
&
original
)
->
ScalarValue
&
{
if
(
&
original
!=
this
)
{
this
->
wrapped
->
CopyFrom
(
*
original
.
wrapped
);
}
return
*
this
;
}
/**
* Move assignment operator.
*/
inline
auto
operator
=
(
ScalarValue
&&
other
)
->
ScalarValue
&
{
if
(
&
other
!=
this
)
{
this
->
wrapped
=
std
::
move
(
other
.
wrapped
);
}
return
*
this
;
}
inline
ScalarValue
(
ProtoScalarValue
*
wrapped
)
:
ProtoMessageWrapper
<
ProtoScalarValue
>
(
wrapped
)
{}
[[
nodiscard
]]
inline
auto
IsNull
()
const
noexcept
->
bool
{
return
(
this
->
wrapped
->
scalar_value_case
()
==
ScalarValueCase
::
kSpecialValue
&&
this
->
wrapped
->
special_value
()
==
ProtoSpecialValue
::
SPECIAL_VALUE_UNSPECIFIED
);
}
[[
nodiscard
]]
inline
auto
IsString
()
const
noexcept
->
bool
{
return
(
this
->
wrapped
->
scalar_value_case
()
==
ScalarValueCase
::
kStringValue
)
||
(
this
->
wrapped
->
scalar_value_case
()
==
ScalarValueCase
::
kSpecialValue
&&
this
->
wrapped
->
special_value
()
==
ProtoSpecialValue
::
SPECIAL_VALUE_EMPTY_STRING
);
}
[[
nodiscard
]]
inline
auto
AsString
()
const
noexcept
->
const
std
::
string
&
{
[[
nodiscard
]]
inline
auto
Get
AsString
()
const
noexcept
->
const
std
::
string
&
{
return
this
->
wrapped
->
string_value
();
}
[[
nodiscard
]]
inline
auto
IsDouble
()
const
noexcept
->
bool
{
return
(
this
->
wrapped
->
scalar_value_case
()
==
ScalarValueCase
::
kDoubleValue
);
}
[[
nodiscard
]]
inline
auto
AsDouble
()
const
noexcept
->
double
{
[[
nodiscard
]]
inline
auto
Get
AsDouble
()
const
noexcept
->
double
{
return
this
->
wrapped
->
double_value
();
}
[[
nodiscard
]]
inline
auto
IsInt
eger
()
const
noexcept
->
bool
{
[[
nodiscard
]]
inline
auto
IsInt
64
()
const
noexcept
->
bool
{
return
(
this
->
wrapped
->
scalar_value_case
()
==
ScalarValueCase
::
kIntegerValue
);
}
[[
nodiscard
]]
inline
auto
AsInt
eger
()
const
noexcept
->
int64_t
{
[[
nodiscard
]]
inline
auto
Get
AsInt
64
()
const
noexcept
->
int64_t
{
return
this
->
wrapped
->
integer_value
();
}
[[
nodiscard
]]
inline
auto
IsBool
()
const
noexcept
->
bool
{
return
(
this
->
wrapped
->
scalar_value_case
()
==
ScalarValueCase
::
kBooleanValue
);
}
[[
nodiscard
]]
inline
auto
AsBool
()
const
noexcept
->
bool
{
[[
nodiscard
]]
inline
auto
Get
AsBool
()
const
noexcept
->
bool
{
return
this
->
wrapped
->
boolean_value
();
}
[[
nodiscard
]]
auto
IsVector
()
const
noexcept
->
bool
{
// Always false b/c a scalar value is never a collection.
return
false
;
}
[[
nodiscard
]]
auto
GetAsVector
()
const
noexcept
->
const
std
::
vector
<
ScalarValue
>
&
{
// Always return an empty vector.
static
const
std
::
vector
<
ScalarValue
>
empty_collection
;
return
empty_collection
;
}
friend
class
Value
;
protected
:
[[
nodiscard
]]
auto
GetProtoValue
()
const
noexcept
->
const
ProtoValue
*
{
if
(
this
->
proto_value
==
nullptr
)
{
this
->
proto_value
=
Arena
::
CreateMessage
<
ProtoValue
>
(
get_arena
());
this
->
proto_value
->
mutable_scalar_value
()
->
CopyFrom
(
*
this
->
wrapped
);
}
return
this
->
proto_value
;
};
inline
ScalarValue
()
:
ProtoMessageWrapper
<
ProtoScalarValue
>
()
{}
private
:
mutable
ProtoValue
*
proto_value
;
};
class
Value
:
public
ProtoMessageWrapper
<
ProtoValue
>
{
class
Value
:
public
AbstractValue
,
public
ProtoMessageWrapper
<
ProtoValue
>
{
public:
/**
* Copy constructor.
*/
inline
Value
(
const
Value
&
original
)
:
Value
()
{
this
->
wrapped
->
CopyFrom
(
*
original
.
wrapped
);
}
/**
* Move constructor.
*/
inline
Value
(
Value
&&
other
)
:
Value
(
std
::
move
(
other
.
wrapped
))
{}
/**
* Destructor.
*/
inline
~
Value
()
{}
inline
Value
()
:
ProtoMessageWrapper
<
ProtoValue
>
()
{
// has NULL_VALUE now
}
explicit
inline
Value
(
const
ScalarValue
&
value
)
:
Value
()
{
this
->
wrapped
->
mutable_scalar_value
()
->
CopyFrom
(
*
value
.
wrapped
);
}
explicit
inline
Value
(
const
AbstractValue
&
value
)
:
Value
(
value
.
GetProtoValue
())
{}
explicit
inline
Value
(
ProtoValue
*
wrapped
)
:
ProtoMessageWrapper
<
ProtoValue
>
(
wrapped
)
{}
explicit
inline
Value
(
const
std
::
string
&
value
)
:
ProtoMessageWrapper
<
ProtoValue
>
()
{
this
->
wrapped
->
mutable_scalar_value
()
->
set_string_value
(
value
);
...
...
@@ -121,7 +305,10 @@ public:
LIST_VALUE_CONSTRUCTOR
(
bool
,
set_boolean_value
)
[[
nodiscard
]]
inline
auto
IsNull
()
const
noexcept
->
bool
{
return
this
->
wrapped
->
value_case
()
==
ValueCase
::
VALUE_NOT_SET
;
return
this
->
wrapped
->
value_case
()
==
ValueCase
::
VALUE_NOT_SET
||
(
this
->
wrapped
->
scalar_value
().
scalar_value_case
()
==
ScalarValueCase
::
kSpecialValue
&&
this
->
wrapped
->
scalar_value
().
special_value
()
==
ProtoSpecialValue
::
SPECIAL_VALUE_UNSPECIFIED
);
}
[[
nodiscard
]]
inline
auto
IsString
()
const
noexcept
->
bool
{
...
...
@@ -134,7 +321,7 @@ public:
}
return
false
;
}
[[
nodiscard
]]
inline
auto
AsString
()
const
noexcept
->
const
std
::
string
&
{
[[
nodiscard
]]
inline
auto
Get
AsString
()
const
noexcept
->
const
std
::
string
&
{
return
this
->
wrapped
->
scalar_value
().
string_value
();
;
}
...
...
@@ -146,18 +333,18 @@ public:
}
return
false
;
}
[[
nodiscard
]]
inline
auto
AsDouble
()
const
noexcept
->
double
{
[[
nodiscard
]]
inline
auto
Get
AsDouble
()
const
noexcept
->
double
{
return
this
->
wrapped
->
scalar_value
().
double_value
();
}
[[
nodiscard
]]
inline
auto
IsInt
eger
()
const
noexcept
->
bool
{
[[
nodiscard
]]
inline
auto
IsInt
64
()
const
noexcept
->
bool
{
if
(
this
->
wrapped
->
value_case
()
==
ValueCase
::
kScalarValue
)
{
return
(
this
->
wrapped
->
scalar_value
().
scalar_value_case
()
==
ScalarValueCase
::
kIntegerValue
);
}
return
false
;
}
[[
nodiscard
]]
inline
auto
AsInt
eger
()
const
noexcept
->
int64_t
{
[[
nodiscard
]]
inline
auto
Get
AsInt
64
()
const
noexcept
->
int64_t
{
return
this
->
wrapped
->
scalar_value
().
integer_value
();
}
...
...
@@ -168,31 +355,55 @@ public:
}
return
false
;
}
[[
nodiscard
]]
inline
auto
AsBool
()
const
noexcept
->
bool
{
[[
nodiscard
]]
inline
auto
Get
AsBool
()
const
noexcept
->
bool
{
return
this
->
wrapped
->
scalar_value
().
boolean_value
();
}
[[
nodiscard
]]
inline
auto
Is
List
()
const
noexcept
->
bool
{
[[
nodiscard
]]
inline
auto
Is
Vector
()
const
noexcept
->
bool
{
return
this
->
wrapped
->
value_case
()
==
ValueCase
::
kListValues
;
}
[[
nodiscard
]]
inline
auto
AsList
()
const
noexcept
->
const
std
::
vector
<
ScalarValue
>
&
{
if
(
!
Is
List
())
{
[[
nodiscard
]]
inline
auto
GetAsVector
()
const
noexcept
->
const
std
::
vector
<
ScalarValue
>
&
{
if
(
!
Is
Vector
())
{
// create empty list
this
->
list
_values
=
std
::
make_unique
<
std
::
vector
<
ScalarValue
>>
();
this
->
collection
_values
=
std
::
make_unique
<
std
::
vector
<
ScalarValue
>>
();
}
if
(
this
->
list
_values
==
nullptr
)
{
this
->
list
_values
=
std
::
make_unique
<
std
::
vector
<
ScalarValue
>>
();
if
(
this
->
collection
_values
==
nullptr
)
{
this
->
collection
_values
=
std
::
make_unique
<
std
::
vector
<
ScalarValue
>>
();
for
(
auto
&
scalar
:
*
(
this
->
wrapped
->
mutable_list_values
()
->
mutable_values
()))
{
this
->
list
_values
->
push_back
(
ScalarValue
(
&
scalar
));
this
->
collection
_values
->
push_back
(
ScalarValue
(
&
scalar
));
}
}
return
*
(
this
->
list
_values
);
return
*
(
this
->
collection
_values
);
}
/**
* Return true if the underlying Protobuf messages have the same
* serialization.
*/
inline
auto
operator
==
(
const
Value
&
other
)
const
noexcept
->
bool
{
return
this
->
wrapped
->
SerializeAsString
()
==
other
.
wrapped
->
SerializeAsString
();
}
/**
* Copy assignment operator.
*/
inline
auto
operator
=
(
const
Value
&
other
)
->
Value
&
{
if
(
&
other
!=
this
)
{
this
->
wrapped
->
CopyFrom
(
*
other
.
wrapped
);
}
return
*
this
;
}
/**
* Move assignment operator.
*/
inline
auto
operator
=
(
Value
&&
other
)
->
Value
&
{
if
(
&
other
!=
this
)
{
this
->
wrapped
=
std
::
move
(
other
.
wrapped
);
}
return
*
this
;
}
inline
auto
ToString
()
const
noexcept
->
const
std
::
string
{
CAOSDB_DEBUG_MESSAGE_STRING
(
*
wrapped
,
out
)
return
out
;
...
...
@@ -201,8 +412,11 @@ public:
friend
class
Entity
;
friend
class
Property
;
protected
:
[[
nodiscard
]]
auto
GetProtoValue
()
const
noexcept
->
const
ProtoValue
*
{
return
this
->
wrapped
;
};
private
:
mutable
std
::
unique_ptr
<
std
::
vector
<
ScalarValue
>>
list
_values
;
mutable
std
::
unique_ptr
<
std
::
vector
<
ScalarValue
>>
collection
_values
;
};
}
// namespace caosdb::entity
...
...
This diff is collapsed.
Click to expand it.
src/ccaosdb.cpp
+
2
−
1
View file @
31ad2cf0
...
...
@@ -23,6 +23,7 @@
#include
"caosdb/connection.h"
#include
"caosdb/constants.h"
#include
"caosdb/data_type.h"
// for DataType, AtomicDat...
#include
"caosdb/entity.h"
#include
"caosdb/value.h"
#include
"caosdb/utility.h"
#include
"caosdb/status_code.h"
...
...
@@ -47,7 +48,7 @@ extern "C" {
#define WRAPPED_MESSAGE_CAST(name) static_cast<caosdb::entity::Message *>(name->wrapped_message)
#define WRAPPED_VALUE_CAST(name) static_cast<caosdb::entity::Value *>(name->wrapped_value)
#define WRAPPED_VALUE_CAST(name) static_cast<caosdb::entity::
Abstract
Value *>(name->wrapped_value)
#define ENUM_NAME_FROM_VALUE(arg, etype) \
caosdb::utility::getEnumNameFromValue<caosdb::entity::etype>(arg)
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment