Skip to content

Commit

Permalink
change snfine to concepts
Browse files Browse the repository at this point in the history
Signed-off-by: i-curve <[email protected]>

#3
  • Loading branch information
i-curve committed Dec 19, 2023
1 parent 4844f2a commit 781d594
Show file tree
Hide file tree
Showing 8 changed files with 335 additions and 85 deletions.
42 changes: 35 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
[![cMake on multiple platforms](https://github.com/i-curve/copypp/actions/workflows/cmake-multi-platform.yml/badge.svg)](https://github.com/i-curve/copypp/actions/workflows/cmake-multi-platform.yml)
[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/nlohmann/json/master/LICENSE.MIT)

support field copy in different c++ struct.
support field copy in different c++ data type.

<!-- @import "[TOC]" {cmd="toc" depthFrom=1 depthTo=6 orderedList=false} -->

Expand All @@ -12,8 +12,8 @@ support field copy in different c++ struct.
- [COPYPP](#copypp)
- [Required](#required)
- [Usage](#usage)
- [struct](#struct)
- [COPY JSON string](#copy-json-string)
- [struct/class](#structclass)
- [json string](#json-string)
- [array copy](#array-copy)
- [Integration](#integration)
- [copy the single header file](#copy-the-single-header-file)
Expand All @@ -40,7 +40,7 @@ include the header file
#include <icurve/copypp.hh>
```

### struct
### struct/class

COPYPP_FIELDS_NON_INTRUSIVE
defination the need to copy class
Expand Down Expand Up @@ -121,7 +121,7 @@ BB b;
icurve::copy(b, a);
```
### COPY JSON string
### json string
copypp support copy between json's string and struct, this copy depency [nlohmann-json](https://github.com/nlohmann/json) library, so you need
Expand Down Expand Up @@ -159,12 +159,22 @@ std::array<BB, 2> b = {BB(1, "first", true), BB(2, "second", false)};
icurve::copy(a, b);
```

span
stl support

copypp support stl copy, condition:

> 1. the source has forward end iterator(begin, end)
> 2. the destiontion has forward iterator(begin, and)
> 3. if the destination has back_insert_iterator, copypp will copy the all source item. Otherwise, it only copy the minimum length between source and destination
copypp can copy it, even in a different stl type.

```c++
AA a[3];
BB b[2] = {BB(1, "first", true), BB(2, "second", false)};
icurve::copy(std::span<AA>(a), std::span<BB>(b));
std::span<AA> aa(a);
std::span<BB> bb(b);
icurve::copy(aa, bb);
```
If it's vector, you can directly use it.
Expand All @@ -175,6 +185,24 @@ vector<BB> b = {BB(1, "first", true), BB(2, "second", false)};
icurve::copy(a, b);
```

different stl type

if the destionation can append item, it will clear destionation and append new item.

```c++
std::vector<AA> a = {AA(1, "first", true), AA(2, "second", false)};
std::list<BB> b; // copy all items
icurve::copy(b, a);
```
```c++
std::vector<AA> a = {AA(1, "first", true), AA(2, "second", false)};
std::array<BB, 1> b;
std::array<BB, 3> c;
icurve::copy(b, a); // will copy 1 item(min(a.size(), b.size())
icurve::copy(c, a); // will copy 2 items(min(a.size(), c.size()))
```

## Integration

---
Expand Down
47 changes: 28 additions & 19 deletions include/icurve/copypp.hh
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@

#include <string>
#include <vector>
#include <vector>
#include <span>
#include <ranges>
#include "meta.hh"

#ifndef NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT
Expand Down Expand Up @@ -64,33 +63,43 @@ void copy(D (&destination)[L1], S (&source)[L2]) {
}
}

template <typename D, size_t L1, typename S, size_t L2>
void copy(std::array<D, L1> &destination, std::array<S, L2> &source) {
size_t len = std::min(L1, L2);
for (int i = 0; i < len; i++) {
icurve::copy(destination[i], source[i]);
}
}
template <typename T>
concept PushBackType = requires(T t) {
t.clear();
t.push_back(std::declval<typename T::value_type>());
};
template <typename T>
concept NoPushBackType = !PushBackType<T>;

#if (_MSC_VER && _MSVC_LANG >= 201703L) || __cplusplus >= 202002L
template <typename D, size_t L1, typename S, size_t L2>
void copy(std::span<D, L1> destination, std::span<S, L2> source) {
size_t len = std::min(L1, L2);
for (int i = 0; i < len; i++) {
icurve::copy(destination[i], source[i]);
template <NoPushBackType D, typename S>
requires requires(D d, S s) {
std::ranges::begin(s);
std::ranges::end(s);
std::ranges::begin(d);
std::ranges::end(d);
}
void copy(D &destination, S &source) {
for (auto dp = destination.begin(), sp = source.begin();
dp != destination.end() && sp != source.end(); ++dp, ++sp) {
icurve::copy(*dp, *sp);
}
}

template <typename D, typename S>
void copy(std::vector<D> &destination, std::vector<S> &source) {
template <PushBackType D, typename S>
requires requires(D d, S s) {
std::ranges::begin(s);
std::ranges::end(s);
std::ranges::begin(d);
std::ranges::end(d);
}
void copy(D &destination, S &source) {
destination.clear();
typename D::value_type tmp;
for (auto &item : source) {
D tmp;
copy(tmp, item);
destination.push_back(tmp);
}
}
#endif

#ifdef NLOHMANN_DEFINE_TYPE_INTRUSIVE
// copy josn string to struct.
Expand Down
47 changes: 27 additions & 20 deletions include/icurve/copypp_only.hh
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

#include <string>
#include <vector>
#include <span>
#include <ranges>
// clang-format off
#ifndef NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT
#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(...)
Expand Down Expand Up @@ -485,36 +485,43 @@ void copy(D (&destination)[L1], S (&source)[L2]) {
icurve::copy(destination[i], source[i]);
}
}
template <typename T>
concept PushBackType = requires(T t) {
t.clear();
t.push_back(std::declval<typename T::value_type>());
};
template <typename T>
concept NoPushBackType = !PushBackType<T>;

template <typename D, size_t L1, typename S, size_t L2>
void copy(std::array<D, L1> &destination, std::array<S, L2> &source) {
size_t len = std::min(L1, L2);
for (int i = 0; i < len; i++) {
icurve::copy(destination[i], source[i]);
}
template <NoPushBackType D, typename S>
requires requires(D d, S s) {
std::ranges::begin(s);
std::ranges::end(s);
std::ranges::begin(d);
std::ranges::end(d);
}

#if (_MSC_VER && _MSVC_LANG >= 201703L) || __cplusplus >= 202002L
template <typename D, size_t L1, typename S, size_t L2>
void copy(std::span<D, L1> destination, std::span<S, L2> source) {
size_t len = std::min(L1, L2);
for (int i = 0; i < len; i++) {
icurve::copy(destination[i], source[i]);
void copy(D &destination, S &source) {
for (auto dp = destination.begin(), sp = source.begin();
dp != destination.end() && sp != source.end(); ++dp, ++sp) {
icurve::copy(*dp, *sp);
}
}

template <typename D, typename S>
void copy(std::vector<D> &destination, std::vector<S> &source) {
template <PushBackType D, typename S>
requires requires(D d, S s) {
std::ranges::begin(s);
std::ranges::end(s);
std::ranges::begin(d);
std::ranges::end(d);
}
void copy(D &destination, S &source) {
destination.clear();
if (source.empty())
return;
typename D::value_type tmp;
for (auto &item : source) {
D tmp;
copy(tmp, item);
destination.push_back(tmp);
}
}
#endif

#ifdef NLOHMANN_DEFINE_TYPE_INTRUSIVE
// copy josn string to struct.
Expand Down
16 changes: 15 additions & 1 deletion test/B.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#pragma once
#include <string>
#include <cassert>
#include "A.h"

class B {
public:
Expand Down Expand Up @@ -31,4 +33,16 @@ class BB {

public:
COPYPP_FIELDS_INTRUSIVE(BB, id, name, sex)
};
};

void checkA(A a, B b) {
assert(a.id == b.id);
assert(a.name == b.name);
assert(a.sex == b.sex);
}

void checkAA(AA a, BB b) {
assert(a.getId() == b.getId());
assert(a.getName() == b.getName());
assert(a.getSex() == b.getSex());
}
9 changes: 7 additions & 2 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ target_link_directories(copypp_test2 PUBLIC ${PROJECT_SOURCE_DIR}/include)
add_test(NAME copypp_test2 COMMAND copypp_test2)

add_executable(copypp_only_test copypp_only_test.cpp)
target_link_libraries(copypp_only_test PRIVATE fmt::fmt-header-only)
target_link_libraries(copypp_only_test PRIVATE fmt::fmt-header-only GTest::gtest GTest::gtest_main)
target_link_directories(copypp_only_test PUBLIC ${PROJECT_SOURCE_DIR}/include)
add_test(NAME copypp_only_test COMMAND copypp_only_test)

Expand All @@ -37,4 +37,9 @@ add_test(NAME copypp_test4 COMMAND copypp_test4)
add_executable(copypp_array_test copypp_array_test.cpp)
target_link_libraries(copypp_array_test PRIVATE GTest::gtest GTest::gtest_main)
target_link_directories(copypp_array_test PUBLIC ${PROJECT_SOURCE_DIR}/include)
add_test(NAME copypp_array_test COMMAND copypp_array_test)
add_test(NAME copypp_array_test COMMAND copypp_array_test)

add_executable(copypp_stl_test copypp_stl_test.cpp)
target_link_libraries(copypp_stl_test PRIVATE fmt::fmt-header-only GTest::gtest GTest::gtest_main)
target_link_directories(copypp_stl_test PUBLIC ${PROJECT_SOURCE_DIR}/include)
add_test(NAME copypp_stl_test COMMAND copypp_stl_test)
60 changes: 53 additions & 7 deletions test/copypp_array_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
*/
#include <iostream>
#include <nlohmann/json.hpp>
#include <list>
#include "icurve/copypp.hh"
#include <gtest/gtest.h>
#include "A.h"
#include "B.h"

TEST(COPYPP_ARRAY, TEXT_KNOW) {
Expand All @@ -29,26 +29,72 @@ TEST(COPYPP_ARRAY, _1) {
BB b[2] = {BB(1, "first", true), BB(2, "second", false)};

icurve::copy(a, b);
// std::copy();
checkAA(a[0], b[0]);
checkAA(a[1], b[1]);
// icurve::copy(std::span<AA>(a, 3), std::span<BB>(b, 2));
// icurve::copy(std::span<AA>(a), std::span<BB>(b));
}

TEST(COPYPP_ARRAY, _2) {
std::array<AA, 2> a;
std::array<BB, 2> b = {BB(1, "first", true), BB(2, "second", false)};
// a.clear();
icurve::copy(a, b);
for (int i = 0; i < 2; i++) {
EXPECT_TRUE(a[i].getId() == b[i].getId());
EXPECT_TRUE(a[i].getName() == b[i].getName());
EXPECT_TRUE(a[i].getSex() == b[i].getSex());
}
}

TEST(COPYPP_ARRAY, _3) {
AA a[3];
BB b[2] = {BB(1, "first", true), BB(2, "second", false)};
std::span<AA> aa(a);
std::span<BB> bb(b);
icurve::copy(aa, bb);
checkAA(aa[0], bb[0]);
checkAA(aa[1], bb[1]);
}

TEST(COPYPP_ARRAY, _4) {
std::vector<AA> a;
std::vector<BB> b = {BB(1, "first", true), BB(2, "second", false)};
// std::back_insert_iterator(a);
// std::vector<AA>::it
// std::back_inserter(b, BB(1, "first", true));
icurve::copy(a, b);
for (int i = 0; i < 2; i++) {
EXPECT_TRUE(a[i].getId() == b[i].getId());
EXPECT_TRUE(a[i].getName() == b[i].getName());
EXPECT_TRUE(a[i].getSex() == b[i].getSex());
}
}

TEST(COPYPP_ARRAY, _5) {
std::list<int> n1;
// std::back_insert(n1, 12);
n1.push_back(5);
}
TEST(COPYPP_ARRAY, _x) {
A a = {3, "minal a", false};
B b;
/// compile error
// icurve::copy(b, a);
int c = 25;
int d;
// icurve::copy(d, c);
icurve::copy(d, c);
}

TEST(COPYPP_ARRAY, tmp) {
int a[3] = {1, 2, 3};

int b[3];
std::copy(a, a + 3, b);
icurve::copy(b, a);
EXPECT_TRUE(a[0] == b[0]);
EXPECT_TRUE(a[1] == b[1]);
EXPECT_TRUE(a[2] == b[2]);
int c = 5;
int d;
// icurve::copy(d, c);
// std::negation<std::bool_constant<true>>;
icurve::copy(d, c);
EXPECT_TRUE(c == d);
}
Loading

0 comments on commit 781d594

Please sign in to comment.