浏览代码

Bug, unknown whenever in vector or variant (see cbor test)

cbor
Ludovic 'Archivist' Lagouardette 4 年前
父节点
当前提交
f36ccc676e
共有 11 个文件被更改,包括 322 次插入220 次删除
  1. +1
    -1
      Makefile
  2. +11
    -0
      include/gp/algorithm/cvref.hpp
  3. +4
    -160
      include/gp/algorithm/modifiers.hpp
  4. +7
    -6
      include/gp/algorithm/move.hpp
  5. +159
    -0
      include/gp/algorithm/reference.hpp
  6. +11
    -1
      include/gp/algorithm/tmp_manip.hpp
  7. +21
    -17
      include/gp/function.hpp
  8. +5
    -0
      include/gp/pair.hpp
  9. +54
    -28
      include/gp/variant.hpp
  10. +3
    -3
      tests.cpp
  11. +46
    -4
      tests/cbor_test.cpp

+ 1
- 1
Makefile 查看文件

@ -1,5 +1,5 @@
CXX= clang++-10
CXXFLAGS= --std=c++20 -O0 -g -pthread -DGP_TESTS -DFUZZ_STRENGTH=500 -DNO_BENCH=0 -pedantic \
CXXFLAGS= --std=c++20 -O0 -g -pthread -DGP_TESTS -DFUZZ_STRENGTH=500 -DNO_BENCH=1 -pedantic \
-fprofile-instr-generate -fcoverage-mapping -Wno-unknown-attributes \
-fsanitize=address -fno-omit-frame-pointer
all: tests

+ 11
- 0
include/gp/algorithm/cvref.hpp 查看文件

@ -0,0 +1,11 @@
#pragma once
namespace gp{
template< class T >
struct remove_cvref {
using type = std::remove_cv_t<std::remove_reference_t<T>>;
};
template< class T >
using remove_cvref_t = typename remove_cvref<T>::type;
}

+ 4
- 160
include/gp/algorithm/modifiers.hpp 查看文件

@ -1,7 +1,10 @@
#pragma once
#include <gp/algorithm/move.hpp>
#include <gp/algorithm/cvref.hpp>
#include <gp/algorithm/reference.hpp>
#include <type_traits>
#include "gp/algorithm/move.hpp"
namespace gp {
@ -25,163 +28,4 @@ namespace gp {
/**
**********************************************************************************************
Code extrated from cppreference.com and the libc++ Library project, licensed under MIT license
**********************************************************************************************
**/
namespace detail {
template <class>
constexpr bool is_reference_wrapper_v = false;
template <class U>
constexpr bool is_reference_wrapper_v<std::reference_wrapper<U>> = true;
template <class T, class Type, class T1, class... Args>
constexpr decltype(auto) INVOKE(Type T::* f, T1&& t1, Args&&... args)
{
if constexpr (std::is_member_function_pointer_v<decltype(f)>) {
if constexpr (std::is_base_of_v<T, std::decay_t<T1>>)
return (gp::forward<T1>(t1).*f)(gp::forward<Args>(args)...);
else if constexpr (is_reference_wrapper_v<std::decay_t<T1>>)
return (t1.get().*f)(gp::forward<Args>(args)...);
else
return ((*gp::forward<T1>(t1)).*f)(gp::forward<Args>(args)...);
} else {
static_assert(std::is_member_object_pointer_v<decltype(f)>);
static_assert(sizeof...(args) == 0);
if constexpr (std::is_base_of_v<T, std::decay_t<T1>>)
return gp::forward<T1>(t1).*f;
else if constexpr (is_reference_wrapper_v<std::decay_t<T1>>)
return t1.get().*f;
else
return (*gp::forward<T1>(t1)).*f;
}
}
template <class F, class... Args>
constexpr decltype(auto) INVOKE(F&& f, Args&&... args)
{
return gp::forward<F>(f)(gp::forward<Args>(args)...);
}
} // namespace detail
template< class F, class... Args>
constexpr std::invoke_result_t<F, Args...> invoke(F&& f, Args&&... args)
noexcept(std::is_nothrow_invocable_v<F, Args...>)
{
return detail::INVOKE(gp::forward<F>(f), gp::forward<Args>(args)...);
}
template< class T >
struct remove_cvref {
using type = std::remove_cv_t<std::remove_reference_t<T>>;
};
template< class T >
using remove_cvref_t = typename remove_cvref<T>::type;
template< class T >
T* addressof(T& arg)
{
return reinterpret_cast<T*>(
&const_cast<char&>(
reinterpret_cast<const volatile char&>(arg)));
}
namespace detail {
template <class T> constexpr T& FUN(T& t) noexcept { return t; }
template <class T> void FUN(T&&) = delete;
}
template <class T>
class reference_wrapper {
public:
// types
typedef T type;
// construct/copy/destroy
template <class U, class = decltype(
detail::FUN<T>(std::declval<U>()),
std::enable_if_t<!std::is_same_v<reference_wrapper, gp::remove_cvref_t<U>>>()
)>
constexpr reference_wrapper(U&& u) noexcept(noexcept(detail::FUN<T>(gp::forward<U>(u))))
: _ptr(gp::addressof(detail::FUN<T>(gp::forward<U>(u)))) {}
reference_wrapper(const reference_wrapper&) noexcept = default;
// assignment
reference_wrapper& operator=(const reference_wrapper& x) noexcept = default;
// access
constexpr operator T& () const noexcept { return *_ptr; }
constexpr T& get() const noexcept { return *_ptr; }
template< class... ArgTypes >
constexpr std::invoke_result_t<T&, ArgTypes...>
operator() ( ArgTypes&&... args ) const {
return gp::invoke(get(), gp::forward<ArgTypes>(args)...);
}
private:
T* _ptr;
};
// deduction guides
template<class T>
reference_wrapper(T&) -> reference_wrapper<T>;
template<typename T>
auto ref(T& vref) {
return reference_wrapper<T>(vref);
}
template <class _DecayFunc>
class __not_fn_imp {
_DecayFunc __fd;
public:
__not_fn_imp() = delete;
template <class ..._Args>
auto operator()(_Args&& ...__args) &
noexcept(noexcept(!gp::invoke(__fd, gp::forward<_Args>(__args)...)))
-> decltype( !gp::invoke(__fd, gp::forward<_Args>(__args)...))
{ return !gp::invoke(__fd, gp::forward<_Args>(__args)...); }
template <class ..._Args>
auto operator()(_Args&& ...__args) &&
noexcept(noexcept(!gp::invoke(gp::move(__fd), gp::forward<_Args>(__args)...)))
-> decltype( !gp::invoke(gp::move(__fd), gp::forward<_Args>(__args)...))
{ return !gp::invoke(gp::move(__fd), gp::forward<_Args>(__args)...); }
template <class ..._Args>
auto operator()(_Args&& ...__args) const&
noexcept(noexcept(!gp::invoke(__fd, gp::forward<_Args>(__args)...)))
-> decltype( !gp::invoke(__fd, gp::forward<_Args>(__args)...))
{ return !gp::invoke(__fd, gp::forward<_Args>(__args)...); }
template <class ..._Args>
auto operator()(_Args&& ...__args) const&&
noexcept(noexcept(!gp::invoke(gp::move(__fd), gp::forward<_Args>(__args)...)))
-> decltype( !gp::invoke(gp::move(__fd), gp::forward<_Args>(__args)...))
{ return !gp::invoke(gp::move(__fd), gp::forward<_Args>(__args)...); }
private:
template <class _RawFunc,
class = std::enable_if_t<!std::is_same<std::decay_t<_RawFunc>, __not_fn_imp>::value>>
explicit __not_fn_imp(_RawFunc&& __rf)
: __fd(gp::forward<_RawFunc>(__rf)) {}
template <class _RawFunc>
friend inline __not_fn_imp<std::decay_t<_RawFunc>> not_fn(_RawFunc&&);
};
template <class _RawFunc>
inline __not_fn_imp<std::decay_t<_RawFunc>> not_fn(_RawFunc&& __fn) {
return __not_fn_imp<std::decay_t<_RawFunc>>(gp::forward<_RawFunc>(__fn));
}
/**
*********************************************************************************************
*/
}

+ 7
- 6
include/gp/algorithm/move.hpp 查看文件

@ -1,6 +1,7 @@
#pragma once
#include "gp/algorithm/tmp_manip.hpp"
#include "gp/algorithm/cvref.hpp"
#include "gp/range.hpp"
namespace gp{
@ -28,7 +29,7 @@ namespace gp{
T& rhs
)
{
k">auto tmp = gp::move(lhs);
n">gp::remove_cvref_t<T> tmp = gp::move(lhs);
lhs = gp::move(rhs);
rhs = gp::move(tmp);
}
@ -39,7 +40,7 @@ namespace gp{
T& rhs
)
{
k">auto tmp = gp::move(lhs);
n">gp::remove_cvref_t<T> tmp = gp::move(lhs);
lhs = gp::move(rhs);
rhs = gp::move(tmp);
}
@ -50,7 +51,7 @@ namespace gp{
T&& rhs
)
{
k">auto tmp = gp::move(lhs);
n">gp::remove_cvref_t<T> tmp = gp::move(lhs);
lhs = gp::move(rhs);
rhs = gp::move(tmp);
}
@ -61,9 +62,9 @@ namespace gp{
T&& rhs
)
{
k">auto tmp = lhs;
lhs = rhs;
rhs = tmp;
n">gp::remove_cvref_t<T> tmp = gp::move(lhs);
lhs = gp::move(rhs);
rhs = gp::move(tmp);
}
template<typename range_in, typename range_out>

+ 159
- 0
include/gp/algorithm/reference.hpp 查看文件

@ -0,0 +1,159 @@
#pragma once
#include <gp/algorithm/move.hpp>
#include <gp/algorithm/cvref.hpp>
namespace gp{
/**
**********************************************************************************************
Code extrated from cppreference.com and the libc++ Library project, licensed under MIT license
**********************************************************************************************
**/
namespace detail {
template <class>
constexpr bool is_reference_wrapper_v = false;
template <class U>
constexpr bool is_reference_wrapper_v<std::reference_wrapper<U>> = true;
template <class T, class Type, class T1, class... Args>
constexpr decltype(auto) INVOKE(Type T::* f, T1&& t1, Args&&... args)
{
if constexpr (std::is_member_function_pointer_v<decltype(f)>) {
if constexpr (std::is_base_of_v<T, std::decay_t<T1>>)
return (gp::forward<T1>(t1).*f)(gp::forward<Args>(args)...);
else if constexpr (is_reference_wrapper_v<std::decay_t<T1>>)
return (t1.get().*f)(gp::forward<Args>(args)...);
else
return ((*gp::forward<T1>(t1)).*f)(gp::forward<Args>(args)...);
} else {
static_assert(std::is_member_object_pointer_v<decltype(f)>);
static_assert(sizeof...(args) == 0);
if constexpr (std::is_base_of_v<T, std::decay_t<T1>>)
return gp::forward<T1>(t1).*f;
else if constexpr (is_reference_wrapper_v<std::decay_t<T1>>)
return t1.get().*f;
else
return (*gp::forward<T1>(t1)).*f;
}
}
template <class F, class... Args>
constexpr decltype(auto) INVOKE(F&& f, Args&&... args)
{
return gp::forward<F>(f)(gp::forward<Args>(args)...);
}
} // namespace detail
template< class F, class... Args>
constexpr std::invoke_result_t<F, Args...> invoke(F&& f, Args&&... args)
noexcept(std::is_nothrow_invocable_v<F, Args...>)
{
return detail::INVOKE(gp::forward<F>(f), gp::forward<Args>(args)...);
}
template< class T >
T* addressof(T& arg)
{
return reinterpret_cast<T*>(
&const_cast<char&>(
reinterpret_cast<const volatile char&>(arg)));
}
namespace detail {
template <class T> constexpr T& FUN(T& t) noexcept { return t; }
template <class T> void FUN(T&&) = delete;
}
template <class T>
class reference_wrapper {
public:
// types
typedef T type;
// construct/copy/destroy
template <class U, class = decltype(
detail::FUN<T>(std::declval<U>()),
std::enable_if_t<!std::is_same_v<reference_wrapper, gp::remove_cvref_t<U>>>()
)>
constexpr reference_wrapper(U&& u) noexcept(noexcept(detail::FUN<T>(gp::forward<U>(u))))
: _ptr(gp::addressof(detail::FUN<T>(gp::forward<U>(u)))) {}
reference_wrapper(const reference_wrapper&) noexcept = default;
// assignment
reference_wrapper& operator=(const reference_wrapper& x) noexcept = default;
// access
constexpr operator T& () const noexcept { return *_ptr; }
constexpr T& get() const noexcept { return *_ptr; }
template< class... ArgTypes >
constexpr std::invoke_result_t<T&, ArgTypes...>
operator() ( ArgTypes&&... args ) const {
return gp::invoke(get(), gp::forward<ArgTypes>(args)...);
}
private:
T* _ptr;
};
// deduction guides
template<class T>
reference_wrapper(T&) -> reference_wrapper<T>;
template<typename T>
auto ref(T& vref) {
return reference_wrapper<T>(vref);
}
template <class _DecayFunc>
class __not_fn_imp {
_DecayFunc __fd;
public:
__not_fn_imp() = delete;
template <class ..._Args>
auto operator()(_Args&& ...__args) &
noexcept(noexcept(!gp::invoke(__fd, gp::forward<_Args>(__args)...)))
-> decltype( !gp::invoke(__fd, gp::forward<_Args>(__args)...))
{ return !gp::invoke(__fd, gp::forward<_Args>(__args)...); }
template <class ..._Args>
auto operator()(_Args&& ...__args) &&
noexcept(noexcept(!gp::invoke(gp::move(__fd), gp::forward<_Args>(__args)...)))
-> decltype( !gp::invoke(gp::move(__fd), gp::forward<_Args>(__args)...))
{ return !gp::invoke(gp::move(__fd), gp::forward<_Args>(__args)...); }
template <class ..._Args>
auto operator()(_Args&& ...__args) const&
noexcept(noexcept(!gp::invoke(__fd, gp::forward<_Args>(__args)...)))
-> decltype( !gp::invoke(__fd, gp::forward<_Args>(__args)...))
{ return !gp::invoke(__fd, gp::forward<_Args>(__args)...); }
template <class ..._Args>
auto operator()(_Args&& ...__args) const&&
noexcept(noexcept(!gp::invoke(gp::move(__fd), gp::forward<_Args>(__args)...)))
-> decltype( !gp::invoke(gp::move(__fd), gp::forward<_Args>(__args)...))
{ return !gp::invoke(gp::move(__fd), gp::forward<_Args>(__args)...); }
private:
template <class _RawFunc,
class = std::enable_if_t<!std::is_same<std::decay_t<_RawFunc>, __not_fn_imp>::value>>
explicit __not_fn_imp(_RawFunc&& __rf)
: __fd(gp::forward<_RawFunc>(__rf)) {}
template <class _RawFunc>
friend inline __not_fn_imp<std::decay_t<_RawFunc>> not_fn(_RawFunc&&);
};
template <class _RawFunc>
inline __not_fn_imp<std::decay_t<_RawFunc>> not_fn(_RawFunc&& __fn) {
return __not_fn_imp<std::decay_t<_RawFunc>>(gp::forward<_RawFunc>(__fn));
}
/**
*********************************************************************************************
*/
}

+ 11
- 1
include/gp/algorithm/tmp_manip.hpp 查看文件

@ -97,7 +97,17 @@ namespace gp{
template<size_t idx, typename T, typename ...rest>
struct r_index_at
{
using type = typename either<idx==sizeof...(rest),T,typename r_index_at<idx,rest...>::type>::type;
using type =
typename either<
idx==sizeof...(rest),
T,
typename r_index_at<idx,rest...>::type
>::type;
};
template<typename U, typename ...rest>
struct first_of {
using type = U;
};
template<typename T, typename U, typename ...rest>

+ 21
- 17
include/gp/function.hpp 查看文件

@ -53,13 +53,7 @@ namespace gp{
}
public:
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wnull-dereference"
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wnull-dereference"
function(allocator& alloc_v)
#pragma GCC diagnostic pop
#pragma clang diagnostic pop
: alloc(alloc_v)
, invokator(nullptr)
, condestructor(nullptr)
@ -144,9 +138,6 @@ namespace gp{
}
~function(){
if(data_size == 0) {
return;
}
if(data_size <= 0) {
return;
}
@ -174,21 +165,34 @@ namespace gp{
alloc = rhs.alloc;
invokator = rhs.invokator;
condestructor = rhs.condestructor;
if(data_size) condestructor(nullptr, data_ptr);
alloc.value().get().deallocate(data_ptr);
data_ptr = rhs.data_size <= sizeof(data_ptr)
/* Cleanup */
if(data_size > sizeof(data_ptr)) {
condestructor(nullptr, data_ptr);
alloc.value().get().deallocate(data_ptr);
} else if(data_size) {
condestructor(nullptr, (char*)&data_ptr);
}
/* Reallocation */
data_size = rhs.data_size;
data_ptr = data_size <= sizeof(data_ptr)
? 0
: details::ensure(
[&](){return alloc.has_value();},
[&](){return (char*)(alloc.value().get().allocate(rhs.data_size));}
);
data_size = rhs.data_size;
gp_config::assertion(!(alloc.has_value() && data_ptr == nullptr), "allocator failed in function");
gp_config::assertion(!(alloc.has_value() && data_size > 8 && data_ptr != nullptr), "allocator failed in function");
if(
data_ptr != nullptr
and rhs.data_ptr != nullptr
) this->condestructor(data_size <= sizeof(data_ptr) ? (char*)&data_ptr : data_ptr, rhs.data_ptr);
data_size > 0
) this->condestructor(
data_size <= sizeof(data_ptr) ? (char*)&data_ptr : data_ptr,
data_size <= sizeof(data_ptr) ? (char*)&rhs.data_ptr : rhs.data_ptr
);
return *this;
}

+ 5
- 0
include/gp/pair.hpp 查看文件

@ -44,6 +44,11 @@ namespace gp{
}
};
template<typename T1, typename T2>
pair<T1, T2> make_pair(T1 f, T2 s) {
return pair<T1, T2>(f, s);
}
template<typename F, typename S>
bool operator==(const pair<F, S>& lhs, const pair<F, S>& rhs) {
return lhs.first == rhs.first and lhs.second == rhs.second;

+ 54
- 28
include/gp/variant.hpp 查看文件

@ -24,38 +24,58 @@ namespace gp{
gp::function<void(void*)> dtor = {[](void*){}, nullopt};
static_assert(all_of_fixed_size<T...>::value, "not fixed");
void buffswap(fixed_variant& oth) {
char tmp[max_size<T...>()];
mvtor(tmp, buffer);
oth.mvtor(buffer, oth.buffer);
mvtor(oth.buffer, tmp);
}
public:
template<typename U, typename = std::enable_if_t<list_contains_class<gp::remove_cvref_t<U>,T...>::value,int>>
fixed_variant()
: fixed_variant(typename first_of<T...>::type{})
{}
template<typename U, std::enable_if_t<list_contains_class<gp::remove_cvref_t<U>,T...>::value,int> = 0>
fixed_variant(U& value)
: index{r_index_of<U, T...>::value}
{
using actual = gp::remove_cvref_t<U>;
new(buffer) actual(value);
dtor = gp::function<void(void*)>([](void* thing){((actual*)thing)->~actual();}, nullopt);
cpytor = gp::function<void(void*, void*)>([](void* src, void* dest){new(dest) actual(*(actual*)src);}, nullopt);
mvtor = gp::function<void(void*, void*)>([](void* src, void* dest){new(dest) actual(gp::move(*(actual*)src));}, nullopt);
dtor = gp::function<void(void*)>([](void* thing){
((actual*)thing)->~actual();
}, nullopt);
cpytor = gp::function<void(void*, void*)>([](void* src, void* dest){
new(dest) actual(*(actual*)src);
}, nullopt);
mvtor = gp::function<void(void*, void*)>([](void* src, void* dest){
new(dest) actual(gp::move(*(actual*)src));
}, nullopt);
cpytor((char*)&value, buffer);
}
static_assert(list_contains_class<int, int>::value, "list_contains_class doesn't work properly");
static_assert(list_contains_class<int, char, int>::value, "list_contains_class doesn't work properly");
static_assert(list_contains_class<int, int, char>::value, "list_contains_class doesn't work properly");
static_assert(list_contains_class<int, char, int, char>::value, "list_contains_class doesn't work properly");
static_assert(!list_contains_class<int, char, char>::value, "list_contains_class doesn't work properly");
template<typename U, k">typename = std::enable_if_t<list_contains_class<gp::remove_cvref_t<U>,T...>::value,int>>
template<typename U, std::enable_if_t<list_contains_class<gp::remove_cvref_t<U>,T...>::value,int> = 0>
fixed_variant(U&& value)
: index{r_index_of<U, T...>::value}
{
using actual = gp::remove_cvref_t<U>;
new(buffer) actual(std::move(value));
dtor = gp::function<void(void*)>([](void* thing){((actual*)thing)->~actual();}, nullopt);
cpytor = gp::function<void(void*, void*)>([](void* src, void* dest){new(dest) actual(*(actual*)src);}, nullopt);
mvtor = gp::function<void(void*, void*)>([](void* src, void* dest){new(dest) actual(gp::move(*(actual*)src));}, nullopt);
dtor = gp::function<void(void*)>([](void* thing){
((actual*)thing)->~actual();
}, nullopt);
cpytor = gp::function<void(void*, void*)>([](void* src, void* dest){
new(dest) actual(*(actual*)src);
}, nullopt);
mvtor = gp::function<void(void*, void*)>([](void* src, void* dest){
new(dest) actual(gp::move(*(actual*)src));
}, nullopt);
mvtor((char*)&value, buffer);
}
fixed_variant(const fixed_variant& oth)
: index{oth.index}
, dtor{oth.dtor}
, cpytor{oth.cpytor}
, mvtor{oth.mvtor}
{
cpytor((char*)oth.buffer, (char*)buffer);
}
fixed_variant(fixed_variant& oth)
@ -68,12 +88,13 @@ namespace gp{
}
fixed_variant(fixed_variant&& oth)
: index{oth.index}
, dtor{oth.dtor}
, cpytor{oth.cpytor}
, mvtor{oth.mvtor}
{
mvtor(buffer, oth.buffer);
gp::swap(dtor, oth.dtor);
gp::swap(cpytor, oth.cpytor);
gp::swap(mvtor, oth.mvtor);
gp::swap(index, oth.index);
oth.index = std::numeric_limits<std::size_t>::max();
mvtor(oth.buffer, buffer);
}
template<typename U>
@ -100,11 +121,16 @@ namespace gp{
void operator=(fixed_variant&& value)
{
buffswap(value);
gp::swap(dtor, value.dtor);
gp::swap(cpytor, value.cpytor);
gp::swap(mvtor, value.mvtor);
gp::swap(index, value.index);
if(index != std::numeric_limits<std::size_t>::max())
{
dtor((void*)buffer);
}
dtor = value.dtor;
cpytor = value.cpytor;
mvtor = value.mvtor;
index = value.index;
value.index = std::numeric_limits<std::size_t>::max();
mvtor(value.buffer, buffer);
}
template<typename U, typename std::enable_if<list_contains_class<U,T...>::value,int>::type>
@ -128,11 +154,11 @@ namespace gp{
{
dtor((void*)buffer);
}
new(buffer) U(gp::move(value));
index = r_index_of<U, T...>::value;
dtor = gp::function([](void* thing){((U*)thing)->~U();}, nullopt);
cpytor = gp::function<void(void*, void*)>([](void* src, void* dest){new(dest) U(*(U*)src);}, nullopt);
mvtor = gp::function<void(void*, void*)>([](void* src, void* dest){new(dest) U(gp::move(*(U*)src));}, nullopt);
mvtor(buffer, value.buffer);
}
~fixed_variant()
@ -158,7 +184,7 @@ namespace gp{
}
template<typename U>
constexpr n">U& is_a()
constexpr kt">bool is_a()
{
if(r_index_of<U, T...>::value == index)
{

+ 3
- 3
tests.cpp 查看文件

@ -23,13 +23,13 @@ int main()
{
++runned;
int value;
try{
// try{
value = test->run();
if(value)
{
std::cout << std::dec << test->name << " failed with "<< value << std::endl;
}
} catch (gp::runtime_error err) {
/* } catch (gp::runtime_error err) {
std::cout << test->name << " failed with an exception: " << err.what() << std::endl;
value = -1;
} catch (gp_config::assert_failure err) {
@ -38,7 +38,7 @@ int main()
} catch (...) {
std::cout << test->name << " failed with an exception" << std::endl;
value = -1;
}
}*/
failed += (value != 0);
}
std::cout << std::dec << "Runned "<<runned<<" tests with "<<failed<<" failures" << std::endl;

+ 46
- 4
tests/cbor_test.cpp 查看文件

@ -12,11 +12,53 @@ struct cbor_test : public test_scaffold {
virtual int run() {
gp::array<char, 4096> store;
gp::arena alloc{&*store.begin(), store.size()};
n">gp::cbor_value data{alloc};
cm">/*gp::cbor_value data{alloc};
auto gen = data.new_object();
gen.emplace_back(gp::cbor_value{uint8_t(12), alloc}, gp::cbor_value{int32_t(-98), alloc});
gen.emplace_back(gp::cbor_value{uint8_t(13), alloc}, gp::cbor_value{uint32_t(98), alloc});
data = gen;
gen.push_back(gp::make_pair(gp::cbor_value{uint8_t(12), alloc}, gp::cbor_value{int32_t(-98), alloc}));
gen.push_back(gp::make_pair(gp::cbor_value{uint8_t(13), alloc}, gp::cbor_value{uint32_t(98), alloc}));
data = gen;*/
using some_int = gp::fixed_variant<int, unsigned int, long long>;
{
some_int a{16};
some_int b = 12u;
b = a;
gp_config::assertion(b.is_a<int>(), "b got wrong type assigned");
}
{
some_int a{16u};
some_int b = a;
gp_config::assertion(b.is_a<unsigned int>(), "b got wrong type assigned");
gp_config::assertion(b.value<unsigned int>() == 16, "b got wrong value assigned");
}
{
some_int a{16u};
some_int b = gp::move(a);
gp_config::assertion(b.is_a<unsigned int>(), "b got wrong type assigned");
gp_config::assertion(b.value<unsigned int>() == 16, "b got wrong value assigned");
}
{
some_int a{16u};
some_int b;
new(&b) some_int(a);
gp_config::assertion(b.is_a<unsigned int>(), "b got wrong type assigned");
gp_config::assertion(b.value<unsigned int>() == 16, "b got wrong value assigned");
}
{
some_int a{16u};
some_int b;
new(&b) some_int(gp::move(a));
gp_config::assertion(b.is_a<unsigned int>(), "b got wrong type assigned");
gp_config::assertion(b.value<unsigned int>() == 16, "b got wrong value assigned");
}
{
gp::vector<some_int> vec{alloc};
vec.emplace_back(12u);
vec.emplace_back(-16);
gp_config::assertion(vec[0].is_a<unsigned int>(), "vec0 got wrong type assigned");
gp_config::assertion(vec[1].is_a<int>(), "vec1 got wrong type assigned");
}
return 0;
}
};

正在加载...
取消
保存