Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
ORNL Quantum Computing Institute
xacc
Commits
7f547d0e
Commit
7f547d0e
authored
Aug 14, 2019
by
Mccaskey, Alex
Browse files
initial commit of heterogenous map
Signed-off-by:
Alex McCaskey
<
mccaskeyaj@ornl.gov
>
parent
2dc1e373
Changes
2
Hide whitespace changes
Inline
Side-by-side
xacc/tests/HeterogeneousTester.cpp
0 → 100644
View file @
7f547d0e
#include
"heterogeneous.hpp"
#include
<gtest/gtest.h>
#include
<stdexcept>
#include
"XACC.hpp"
// class print_visitor : public xacc::visitor_base<int, double, std::string>
// {
// public:
// template<class T>
// void operator()(T& _in)
// {
// std::cout << _in << " ";
// }
// };
TEST
(
HeterogeneousMapTester
,
checkSimple
)
{
xacc
::
HeterogeneousMap
c
;
c
.
insert
(
"intkey"
,
1
);
c
.
insert
(
"intkey2"
,
2
);
c
.
insert
(
"doublekey"
,
2.2
);
c
.
insert
(
"variable"
,
std
::
string
{
"t0"
});
EXPECT_EQ
(
2
,
c
.
number_of
<
int
>
());
EXPECT_EQ
(
2.2
,
c
.
get
<
double
>
(
"doublekey"
));
EXPECT_TRUE
(
c
.
keyExists
<
int
>
(
"intkey"
));
EXPECT_TRUE
(
c
.
keyExists
<
std
::
string
>
(
"variable"
));
EXPECT_FALSE
(
c
.
keyExists
<
int
>
(
"random"
));
EXPECT_EQ
(
"t0"
,
c
.
get
<
std
::
string
>
(
"variable"
));
EXPECT_ANY_THROW
(
c
.
get_with_throw
<
bool
>
(
"test"
));
auto
provider
=
xacc
::
getIRProvider
(
"gate"
);
auto
f
=
provider
->
createFunction
(
"f"
,
{});
c
.
insert
(
"function"
,
f
);
EXPECT_EQ
(
"f"
,
c
.
get
<
std
::
shared_ptr
<
xacc
::
Function
>>
(
"function"
)
->
name
());
xacc
::
HeterogeneousMap
m2
{
std
::
make_pair
(
"doublekey"
,
2.0
),
std
::
make_pair
(
"intkey"
,
22
),
std
::
make_pair
(
"function"
,
f
)};
EXPECT_EQ
(
2.0
,
m2
.
get
<
double
>
(
"doublekey"
));
EXPECT_EQ
(
22
,
m2
.
get
<
int
>
(
"intkey"
));
EXPECT_EQ
(
"f"
,
m2
.
get
<
std
::
shared_ptr
<
xacc
::
Function
>>
(
"function"
)
->
name
());
xacc
::
HeterogeneousMap
m3
(
std
::
make_pair
(
"doublekey"
,
2.0
),
std
::
make_pair
(
"intkey"
,
22
),
std
::
make_pair
(
"function"
,
f
));
EXPECT_EQ
(
2.0
,
m3
.
get
<
double
>
(
"doublekey"
));
EXPECT_EQ
(
22
,
m3
.
get
<
int
>
(
"intkey"
));
EXPECT_EQ
(
"f"
,
m3
.
get
<
std
::
shared_ptr
<
xacc
::
Function
>>
(
"function"
)
->
name
());
xacc
::
HeterogeneousMap
cc
;
EXPECT_ANY_THROW
(
cc
.
get_with_throw
<
int
>
(
"intkey"
));
}
int
main
(
int
argc
,
char
**
argv
)
{
xacc
::
Initialize
();
::
testing
::
InitGoogleTest
(
&
argc
,
argv
);
auto
ret
=
RUN_ALL_TESTS
();
xacc
::
Finalize
();
return
ret
;
}
xacc/utils/heterogeneous.hpp
0 → 100644
View file @
7f547d0e
#ifndef XACC_HETEROGENEOUS_HPP_
#define XACC_HETEROGENEOUS_HPP_
#include
<map>
#include
<stdexcept>
#include
<vector>
#include
<unordered_map>
#include
<functional>
#include
<iostream>
#include
<experimental/type_traits>
#include
"variant.hpp"
#include
"Utils.hpp"
namespace
xacc
{
template
<
class
...
>
struct
type_list
{};
template
<
class
...
TYPES
>
struct
visitor_base
{
using
types
=
xacc
::
type_list
<
TYPES
...
>
;
};
class
HeterogeneousMap
{
public:
HeterogeneousMap
()
=
default
;
HeterogeneousMap
(
const
HeterogeneousMap
&
_other
)
{
*
this
=
_other
;
}
template
<
typename
T
>
void
loop_pairs
(
T
value
)
{
insert
(
value
.
first
,
value
.
second
);
}
template
<
typename
First
,
typename
...
Rest
>
void
loop_pairs
(
First
firstValue
,
Rest
...
rest
)
{
loop_pairs
(
firstValue
);
loop_pairs
(
rest
...);
}
template
<
typename
...
TYPES
>
HeterogeneousMap
(
TYPES
&&
...
list
)
{
loop_pairs
(
list
...);
}
HeterogeneousMap
&
operator
=
(
const
HeterogeneousMap
&
_other
)
{
clear
();
clear_functions
=
_other
.
clear_functions
;
copy_functions
=
_other
.
copy_functions
;
size_functions
=
_other
.
size_functions
;
for
(
auto
&&
copy_function
:
copy_functions
)
{
copy_function
(
_other
,
*
this
);
}
return
*
this
;
}
template
<
class
T
>
void
insert
(
const
std
::
string
key
,
const
T
&
_t
)
{
// don't have it yet, so create functions for printing, copying, moving, and
// destroying
if
(
items
<
T
>
.
find
(
this
)
==
std
::
end
(
items
<
T
>
))
{
clear_functions
.
emplace_back
(
[](
HeterogeneousMap
&
_c
)
{
items
<
T
>
.
erase
(
&
_c
);
});
// if someone copies me, they need to call each copy_function and pass
// themself
copy_functions
.
emplace_back
(
[](
const
HeterogeneousMap
&
_from
,
HeterogeneousMap
&
_to
)
{
items
<
T
>
[
&
_to
]
=
items
<
T
>
[
&
_from
];
});
size_functions
.
emplace_back
(
[](
const
HeterogeneousMap
&
_c
)
{
return
items
<
T
>
[
&
_c
].
size
();
});
}
items
<
T
>
[
this
].
insert
({
key
,
_t
});
}
template
<
class
T
>
const
T
&
get
(
const
std
::
string
key
)
const
{
if
(
!
items
<
T
>
.
count
(
this
)
&&
!
items
<
T
>
[
this
].
count
(
key
))
{
XACCLogger
::
instance
()
->
error
(
"Invalid type ("
+
std
::
string
(
typeid
(
T
).
name
())
+
") or key ("
+
key
+
")."
);
print_backtrace
();
}
return
items
<
T
>
[
this
][
key
];
}
template
<
class
T
>
const
T
&
get_with_throw
(
const
std
::
string
key
)
const
{
if
(
!
items
<
T
>
.
count
(
this
)
&&
!
items
<
T
>
[
this
].
count
(
key
))
{
throw
new
std
::
runtime_error
(
"Invalid type ("
+
std
::
string
(
typeid
(
T
).
name
())
+
")."
);
}
return
items
<
T
>
[
this
][
key
];
}
void
clear
()
{
for
(
auto
&&
clear_func
:
clear_functions
)
{
clear_func
(
*
this
);
}
}
template
<
class
T
>
size_t
number_of
()
const
{
auto
iter
=
items
<
T
>
.
find
(
this
);
if
(
iter
!=
items
<
T
>
.
cend
())
return
items
<
T
>
[
this
].
size
();
return
0
;
}
template
<
typename
T
>
bool
keyExists
(
const
std
::
string
key
)
const
{
if
(
items
<
T
>
.
count
(
this
)
&&
items
<
T
>
[
this
].
count
(
key
))
{
return
true
;
}
return
false
;
}
size_t
size
()
const
{
size_t
sum
=
0
;
for
(
auto
&&
size_func
:
size_functions
)
{
sum
+=
size_func
(
*
this
);
}
// gotta be careful about this overflowing
return
sum
;
}
~
HeterogeneousMap
()
{
clear
();
}
template
<
class
T
>
void
visit
(
T
&&
visitor
)
{
visit_impl
(
visitor
,
typename
std
::
decay_t
<
T
>::
types
{});
}
private:
template
<
class
T
>
static
std
::
unordered_map
<
const
HeterogeneousMap
*
,
std
::
map
<
std
::
string
,
T
>>
items
;
template
<
class
T
,
class
U
>
using
visit_function
=
decltype
(
std
::
declval
<
T
>
().
operator
()(
std
::
declval
<
U
&>
()));
template
<
class
T
,
class
U
>
static
constexpr
bool
has_visit_v
=
std
::
experimental
::
is_detected
<
visit_function
,
T
,
U
>::
value
;
template
<
class
T
,
template
<
class
...
>
class
TLIST
,
class
...
TYPES
>
void
visit_impl
(
T
&&
visitor
,
TLIST
<
TYPES
...
>
)
{
using
expander
=
int
[];
(
void
)
expander
{
0
,
(
void
(
visit_impl_help
<
T
,
TYPES
>
(
visitor
)),
0
)...};
}
template
<
class
T
,
class
U
>
void
visit_impl_help
(
T
&
visitor
)
{
static_assert
(
has_visit_v
<
T
,
U
>
,
"Visitors must provide a visit function "
"accepting a reference for each type"
);
for
(
auto
&&
element
:
items
<
U
>
[
this
])
{
visitor
(
element
);
}
}
std
::
vector
<
std
::
function
<
void
(
HeterogeneousMap
&
)
>>
clear_functions
;
std
::
vector
<
std
::
function
<
void
(
const
HeterogeneousMap
&
,
HeterogeneousMap
&
)
>>
copy_functions
;
std
::
vector
<
std
::
function
<
size_t
(
const
HeterogeneousMap
&
)
>>
size_functions
;
};
template
<
class
T
>
std
::
unordered_map
<
const
HeterogeneousMap
*
,
std
::
map
<
std
::
string
,
T
>>
HeterogeneousMap
::
items
;
template
<
typename
...
Types
>
class
Variant
:
public
mpark
::
variant
<
Types
...
>
{
private:
class
ToStringVisitor
{
public:
template
<
typename
T
>
std
::
string
operator
()(
const
T
&
t
)
const
{
std
::
stringstream
ss
;
ss
<<
t
;
return
ss
.
str
();
}
};
class
IsArithmeticVisitor
{
public:
template
<
typename
T
>
bool
operator
()(
const
T
&
t
)
const
{
return
std
::
is_arithmetic
<
T
>::
value
;
}
};
template
<
typename
To
,
typename
From
>
class
CastVisitor
{
public:
To
operator
()(
const
From
&
t
)
const
{
return
(
To
)
t
;
}
};
public:
Variant
()
:
mpark
::
variant
<
Types
...
>
()
{}
template
<
typename
T
>
Variant
(
T
&
element
)
:
mpark
::
variant
<
Types
...
>
(
element
)
{}
template
<
typename
T
>
Variant
(
T
&&
element
)
:
mpark
::
variant
<
Types
...
>
(
element
)
{}
Variant
(
const
Variant
&
element
)
:
mpark
::
variant
<
Types
...
>
(
element
)
{}
template
<
typename
T
>
T
as
()
const
{
try
{
// First off just try to get it
return
mpark
::
get
<
T
>
(
*
this
);
}
catch
(
std
::
exception
&
e
)
{
std
::
stringstream
s
;
s
<<
"InstructionParameter::this->toString() = "
<<
toString
()
<<
"
\n
"
;
s
<<
"This InstructionParameter type id is "
<<
this
->
which
()
<<
"
\n
"
;
XACCLogger
::
instance
()
->
error
(
"Cannot cast Variant to ("
+
std
::
string
(
typeid
(
T
).
name
())
+
"):
\n
"
+
s
.
str
());
print_backtrace
();
exit
(
0
);
}
return
T
();
}
template
<
typename
T
>
T
as_no_error
()
const
{
// First off just try to get it
return
mpark
::
get
<
T
>
(
*
this
);
}
int
which
()
const
{
return
this
->
index
();
}
bool
isNumeric
()
const
{
IsArithmeticVisitor
v
;
return
mpark
::
visit
(
v
,
*
this
);
}
bool
isVariable
()
const
{
try
{
mpark
::
get
<
std
::
string
>
(
*
this
);
}
catch
(
std
::
exception
&
e
)
{
return
false
;
}
return
true
;
}
const
std
::
string
toString
()
const
{
ToStringVisitor
vis
;
return
mpark
::
visit
(
vis
,
*
this
);
}
bool
operator
==
(
const
Variant
<
Types
...
>
&
v
)
const
{
return
v
.
toString
()
==
toString
();
}
bool
operator
!=
(
const
Variant
<
Types
...
>
&
v
)
const
{
return
!
operator
==
(
v
);
}
};
}
// namespace xacc
#endif
\ No newline at end of file
Write
Preview
Supports
Markdown
0%
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!
Cancel
Please
register
or
sign in
to comment