include <iostream>
include "GL3TestCase.h"
include "TestCase.h"
include <string>
include <vector>
include <memory>
include <unordered_set>
include<stdio.h>
include<string.h>
include<stdlib.h>
include<unistd.h>
include<pthread.h>
include <map>
include "texture_external.glsl"
include <thread> // std::thread
include <atomic> // std::atomic, std::atomic_flag, ATOMIC_FLAG_INIT
using namespace deqp;
using namespace tcu;
using namespace std;
include <iostream>
include <vector>
char *thread_func1(void *arg) {
pid_t pid = getpid();
pthread_t tid = pthread_self();
printf("%s pid: %u, tid: %u (0x%x)\n", (char *) arg, (unsigned int) pid, tid, tid);
char *msg = "thread_func1";
return msg;
}
void *thread_func2(void *arg) {
pid_t pid = getpid();
pthread_t tid = pthread_self();
printf("%s pid: %u, tid: %u (0x%x)\n", (char *) arg, (unsigned int) pid, tid, tid);
char *msg = "thread_func2 ";
while (1) {
printf("%s running\n", msg);
sleep(1);
}
return NULL;
}
//int main_thread() {
// pthread_t tid1, tid2;
// if (pthread_create(&tid1, NULL, (void *) thread_func1, "new thread:") != 0) {
// printf("pthread_create error.");
// exit(EXIT_FAILURE);
// }
//
// if (pthread_create(&tid2, NULL, (void *) thread_func2, "new thread:") != 0) {
// printf("pthread_create error.");
// exit(EXIT_FAILURE);
// }
// pthread_detach(tid2);
//
// char *rev = NULL;
// pthread_join(tid1, (void *) &rev);
// printf("%s return.\n", rev);
// pthread_cancel(tid2);
//
// printf("main thread end.\n");
// return 0;
//}
/**
-
不使用,virtual 虚析构函数的话,会造成向上转型为基类,析构基类时不知道自己有子类,导致子类内存泄漏。
*/
class A : public enable_shared_from_this<A> {
public:
A() { std::cout << " A "; }virtual ~A() { std::cout << " ~A "; }
int *data;
int operator() const { return data; }
std::shared_ptr<A> getSharedPtr() {
return shared_from_this();
}virtual void f() {
std::cout << "a\n";
}
};
class B : A {
public:
B() { std::cout << " B "; }
~B() { std::cout << " ~B "; }
void f() override { // 'override' 可选
std::cout << "b\n";
}
};
class C : B {
public:
C(const char *chars) { std::cout << " C "; }
~C() { std::cout << " ~C "; }
void f() override { // 'override' 可选
std::cout << "c\n";
}
};
void test_virtual() {
{
B *b = (B *) new C("cc");
delete b;
}
std::cout << " end\n";
B b;
b.f();
C c("cc");
c.f();
B *b_c = (B *) &c;
b_c->f();
int *data;
{
A a;
a.data = new int[4]{99, 111, 222, 444};
data = (*a);
}
printf("1 %d %d \n", data[0], data[1]);
}
//走了默认的赋值copy构造
void test_default_copy() {
A a;
A aa;
a.data = new int[4]{99, 111, 222, 444};
aa = a;
printf("1 %s %p %p %d\n", aa.data, &(aa.data), aa.data + 1, aa.data[0]);
printf("2 %s %p %p %d\n", a.data, &(a.data), a.data, a.data[0]);
//一个int占用 4字节
// 1 c 0x7ffeee5860c8 0x7facb7402cf4 99
// 2 c 0x7ffeee5860d8 0x7facb7402cf0 99
}
enum ObjectType {
NO_OBJECT,
OBJECT_JS,
OBJECT_NATIVE,
END
};
template<typename T>
struct template_class {
T *data;
};
void test_template() {
template_class<int> t1{};
t1.data = new int[8];
t1.data[0] = 99;
printf("test_template %d %d \n", t1.data[0], t1.data[1]);
ObjectType a = ObjectType::OBJECT_NATIVE;
ObjectType b = a;
ObjectType c(b);
printf("test_template ObjectType %d %d %d \n", a, b, c);
}
class Intvec {
public:
explicit Intvec(size_t num = 0)
: m_size(num), m_data(new int[m_size]) {
log("constructor ", m_size);
}
~Intvec() {
log("destructor");
toString();
if (m_data) {
delete[] m_data;
m_data = nullptr;
}
}
Intvec(Intvec &&other) {
log("move constructor && ");
m_size = other.m_size;
m_data = other.m_data;
other.m_data = nullptr;
other.m_size = 0;
}
Intvec(const Intvec &other)
: m_size(other.m_size), m_data(new int[m_size]) {
log("copy constructor");
for (size_t i = 0; i < m_size; ++i)
m_data[i] = other.m_data[i];
}
//
Intvec &operator=(Intvec &other) {
log("copy assignment operator &");
Intvec tmp(other);
std::swap(m_size, tmp.m_size);
std::swap(m_data, tmp.m_data);
// why!!!
// std::swap(m_data, other.m_data);
return *this;
}
Intvec &operator=(const Intvec &other) {
log("copy assignment operator const &");
Intvec tmp(other);
std::swap(m_size, tmp.m_size);
std::swap(m_data, tmp.m_data);
// why!!!
// std::swap(m_data, other.m_data);
return *this;
}
//
Intvec &operator=(Intvec &&other) {
log("move assignment operator && ");
std::swap(m_size, other.m_size);
std::swap(m_data, other.m_data);
return *this;
}
public:
void log(const char *msg) {
cout << "[" << this << "] " << msg << "\n";
}
void log(const char *msg, int count) {
cout << "[" << this << "] " << msg << " " << count << "\n";
}
void toString() {
cout << "----toString " << this << " Intvec[" << this->m_data << "] " << this->m_size << "\n";
}
size_t m_size;
int *m_data;
};
void modify_intvec(const Intvec *intvec) {
// intvec->m_data = new int[10];
int *tmp_data = intvec->m_data;
// tmp_data = new int[10];
tmp_data[0] = 100;
tmp_data[1] = 200;
intvec->m_data[9] = 10;
// intvec->m_data = nullptr;
}
Intvec getIntPoint() {
Intvec intvec(10);
return intvec;
// const Intvec *intvec = new Intvec();
// intvec->m_data[0] = 1;
// return *intvec;
}
void modify_left(Intvec &&intvec) {
{
Intvec intvec_10(10);
std::swap(intvec.m_data, intvec_10.m_data);
}
cout << "\n ---end modify_left--\n";
}
void modify_left_string(std::string &&msg) {
cout << " ---end modify_left_string--" << msg.data();
}
class ReferenceIntvec {
private:
Intvec &intvec;
public:
void setIntvec(Intvec &intvec) {
cout << "\n ---ReferenceIntvec setIntvec Start--";
ReferenceIntvec::intvec = intvec;
cout << " ---ReferenceIntvec End--\n";
}
ReferenceIntvec(Intvec &intvec) : intvec(intvec) {
cout << "\n ---ReferenceIntvec default Start--";
// ReferenceIntvec::intvec = intvec;
cout << " ---ReferenceIntvec default End--\n";
}
virtual ~ReferenceIntvec() {
cout << " --- ~ReferenceIntvec--\n";
}
int getSize() {
cout << "getSize " << &intvec << " data ptr " << intvec.m_data;
printf(" %p %p", &intvec, intvec.m_data);
return intvec.m_size;
}
};
ReferenceIntvec *test_referenceIntvec(Intvec &intvec) {
cout << "\n ---test_referenceIntvec Start--";
ReferenceIntvec *referenceIntvec = new ReferenceIntvec(intvec);
// referenceIntvec.setIntvec(intvec);
cout << referenceIntvec->getSize() << " ---test_referenceIntvec End--\n";
return referenceIntvec;
}
void modify_normal(Intvec intvec) {
}
void modify_unique_copy(std::unique_ptr<Intvec> intvec) {
}
void modify_unique_reference(std::unique_ptr<Intvec> &intvec) {
}
std::unique_ptr<Intvec> return_modify_unique_copy() {
std::unique_ptr<Intvec> intvec_temp(new Intvec(10));
return intvec_temp;
}
void f(Intvec *p) {
p->m_size = 10; // (p.operator->())->m_size = 10
}
/**
- 绑定env并判断入参列表是否存在null,为null则直接return
*/
define ATTACH_JNI_ENV_AND_RETURN_WHEN_CHECK_NP(tag, sum, ...)\
bool needsDetach = false;\
if(IsNullPoint(sum,__VA_ARGS__)){\
printf("%s GetJniEnvSafe null point \n",tag);\
}\
bool IsNullPoint(int sum, ...) {
va_list point;
va_start(point, sum);
for (int i = 0; i < sum; i++) {
void *result = va_arg(point, void * );
if (result == nullptr) {
va_end(point);
return true;
}
}
va_end(point);
return false;
}
void getIntResult(int **result) {
printf("after %p", result);
int temp = new int[3];
(result) = temp;
temp[0] = 110;
}
struct structA {
int *a;
int *b;
//
// ~structA() {
// delete[] a;
// }
};
void getIntResult2(structA &structA1) {
structA1.a = new int[10];
// structA1.b = new int[10];
structA1.a[0] = 991;
// structA1.b[0] = 903;
}
std::thread::id main_thread_id = std::this_thread::get_id();
void is_main_thread() {
__thread_id id = std::this_thread::get_id();
if (main_thread_id == id)
std::cout << "This is the main thread.\n";
else
std::cout << "This is not the main thread.\n";
}
struct ColorStop {
float offset;
std::string color;
ColorStop() {
printf("ColorStop() %p \n", this);
}
ColorStop(float offset, const std::string &color) : offset(offset), color(color) {
printf("ColorStop(float) %p \n", this);
}
~ColorStop() {
printf("~ColorStop destory %p \n", this);
}
friend ostream &operator<<(ostream &os, const ColorStop &stop) {
os << "offset: " << stop.offset << " color: " << stop.color;
return os;
}
};
class Gradient {
public:
float start[3];
std::vector<ColorStop> colorStops;
};
void pointer_func(const int *p, std::size_t size) {
std::cout << "data = ";
for (std::size_t i = 0; i < size; ++i)
std::cout << p[i] << ' ';
std::cout << '\n';
}
int func_vector() {
// input array
void *src = new float[5]{1.2f, 2.3f, 3.0f, 4.0f, 5.1f};
// int src[] = {1, 2, 3, 4, 5};
// int n = sizeof(src) / sizeof(src[0]);
auto *src_float = (float *) src;
std::vector<float> dest(src_float, src_float + 5);
for (float i: dest) {
std::cout << i << " ";
}
std::cout << " \n";
Gradient gradientB;
{
Gradient gradientA;
ColorStop colorStop(2.0f, "abc");
gradientA.start[0] = 99;
gradientA.colorStops.push_back(colorStop);
gradientB = gradientA;
}
std::cout << gradientB.colorStops.data()[0] << " \n";
return 0;
}
void test_cmp_str() {
modify_left(Intvec(100));//rValue
modify_left_string("adga12345中文呢也可以?么12345asdbsrg");//rValue
std::string string_equ("123456 ");
char *chars_equ = "123456 ";
printf("\n before chars_equ:%d,%s, string_equ:%d,%s, \n", strlen(chars_equ), chars_equ,
string_equ.size(), string_equ.data());
int length = strlen(chars_equ);
char *mSystemFontLocation = new char[length + 1];
strcpy(mSystemFontLocation, chars_equ);
mSystemFontLocation[4] = '\0';
mSystemFontLocation[9] = '1';
printf("\n before mSystemFontLocation:%d,%s \n", strlen(mSystemFontLocation), mSystemFontLocation);
}
void swap_string() {
// Intvec intArray[10];
// intArray[0].m_size;
// void *void_ptr = static_cast< void *>(((&intArray[1])));
cout << "\n ---test1--\n";
{
structA structA1;
getIntResult2(structA1);
if (structA1.a) {
printf("structA1 a %d", structA1.a[0]);
}
if (structA1.b == nullptr) {
printf("structA1 b %p", structA1.b);
}
int *result = nullptr;
printf("before %p", &result);
getIntResult(&result);
cout << "getIntResult " << result[0] << endl;
// std::unique_ptr<Intvec> ptr1;
// ptr1 = return_modify_unique_copy();
}
cout << "\n ---test2--\n";
{
test_virtual();
}
{
test_cmp_str();
}
{
Intvec *intvec_temp = new Intvec(6);
void *intvec_temp_1 = intvec_temp;
delete intvec_temp;
intvec_temp = nullptr;
char *intvec_temp_2 = reinterpret_cast<char *>(intvec_temp_1);
printf("intvec_temp %p %p %p , %d", intvec_temp, intvec_temp_1, intvec_temp_2,
intvec_temp_2);
}
cout << "\n ---end--\n";
if (true) {
return;
}
cout << "\n ---test3--\n";
{
test_default_copy();
}
cout << "\n ---test4--\n";
{
cout << TEXTURE_EXTERNAL_SHADER_PS << endl;
char *str_ = new char[100]{"12345678901234567890123456789012345678901234567890123456789012345678901234567890"};
std::string a(str_);
// delete[] str_;
str_[0] = '0';
str_[1] = '0';
printf("modify a %s %s", a.data(), "~~~");
printf("modify str %s", str_);
a = "abcde";
if (a == "abcde") {
cout << " == abcde \n";
}
test_template();
}
cout << "\n ---test5--\n";
{
string *a = nullptr;
string *b = nullptr;
string *c = nullptr;
ATTACH_JNI_ENV_AND_RETURN_WHEN_CHECK_NP("test5", 3, a, b, c);
}
Intvec *Intvec_100;
Intvec *Intvec_101;
cout << "\n ---test6 unique_ptr release--\n";
{
Intvec_100 = new Intvec();
std::unique_ptr<Intvec> temp(Intvec_100);
temp->m_size = 100;
temp->m_data[0] = 999;
Intvec_101 = temp.release();
}
cout << "\n ---test6_1--\n";
// cout << Intvec_100->m_data[0] << "\n "; //直接闪退
cout << Intvec_101->m_data[0] << "\n "; //直接闪退
cout << "\n ---test7 move constructor map 1 重写move operator= 2不要从Map中取对象存在 增加、删除、使用(直接用)\n";
{
int obja = 10;
int *a = &obja;
int *b = new int[10];
// delete[] a;
delete[] b;
std::map<std::string, Intvec> IntvecMap;
Intvec temp1(100);
//给到std::map 先走默认构造Intvec,然后走move 等号&&操作符,更新值。所以要自行实现。
IntvecMap["abc"] = std::move(temp1);
auto result = IntvecMap.find("abc");
if (result != IntvecMap.end()) {
cout << "\nIntvecMap find " << result->first << "\n";
} else {
cout << "\nIntvecMap not find " << "\n";
}
// Intvec temp2 = IntvecMap["abc"]; 不要这样用!!!!因为会走copy!!最好是用如下方案.直接使用
cout << "\n m_size: " << IntvecMap["abc"].m_size << "\n";
// erase all odd numbers from c
for (auto it = IntvecMap.begin(); it != IntvecMap.end();) {
Intvec temp = std::move(it->second);
it = IntvecMap.erase(it);
cout << "erase" << temp.m_size << " end \n";
}
cout << "\n erase end\n";
//创建Intvec_1直接走move构造函数
// Intvec Intvec_1 = std::move(temp1);
}
cout << "\n ---test8-- default copy 使用引用走默认的copy很容易出问题的\n";
{
structA a;
structA b;
a.a = new int[3];
a.b = new int[3];
a.a[0] = 991;
a.b[0] = 119;
cout << a.a << "_" << a.b << endl;
cout << b.a << "_" << b.b << endl;
b = a;
cout << b.a << "_" << b.b << endl;
}
cout << "\n ---test9-- return unique_ptr\n";
{
std::unique_ptr<Intvec> ptr1;
ptr1 = return_modify_unique_copy();
cout << "\n" << ptr1->m_size << "\n";
// ptr1.release(); 人为泄漏
}
cout << "\n ---test10-- thread\n";
{
is_main_thread();
std::thread foo;
std::thread bar(is_main_thread);
std::cout << "foo: " << foo.joinable() << '\n';
std::cout << "foo: " << bar.joinable() << '\n';
bar.join();
}
cout << "\n ---end--\n";
cout << "\n ---test11-- return vector\n";
{
func_vector();
}
if (true) {
return;
}
cout << "\n ---swap_string--\n";
Intvec aa(10);
Intvec intvec1(getIntPoint());
cout << "\n ---swap_string1--\n";
intvec1 = getIntPoint();
cout << "\n ---swap_string2--\n";
modify_normal(intvec1); //作为函数入参是走的 构造函数。作为出参走等号赋值时走的符号重载
string a_str = "abc";
string b_str = "def";
a_str = std::move(b_str); //string重载了 移动赋值操作符 operator=(string&&),内部有swap操作。最终 b_str的内容为null
// a_str = b_str; //重载的是 复制赋值操作符 operator=(const string&)
cout << "\n ---swap_string end--\n" << a_str << b_str.data();
modify_left(getIntPoint());//rValue
modify_left(Intvec(100));//rValue
Intvec intvec = getIntPoint();
// modify_left(intvec);//lValue
// modify_left(static_cast<Intvec&&>(intvec));//lValue -> rValue
modify_left(std::move(intvec));//lValue -> rValue
std::unique_ptr<Intvec> up_intvec_1(new Intvec(10));
std::unique_ptr<Intvec> up_intvec_2(std::move(up_intvec_1));
// std::unique_ptr<Intvec> up_intvec_3(up_intvec_1);
std::auto_ptr<Intvec> auto_ptr1;
auto_ptr1 = auto_ptr1;
up_intvec_2 = move(up_intvec_1);
modify_unique_copy(std::move(up_intvec_2));
modify_unique_reference(up_intvec_2);
cout << "\n ---start--\n";
// Intvec intvec = getIntPoint();
// modify_left(intvec);
Intvec intvec2;
intvec2 = intvec;
int *a = new int[3];
a[0] = 10;
int *b = new int[3];
b[0] = 20;
cout << "swap_string " << a << " " << b << endl;
//地址级别的交换
std::swap(a, b);
cout << "swap_string " << a << " " << b << endl;
printf("%d %d \n", a[0], b[0]);
}
void test_reference() {
Intvec v1(20);
Intvec v2;
//
// cout << "assigning lvalue...\n";
// v2 = v1;
// cout << "ended assigning lvalue...\n";
cout << "assigning rvalue...\n";
v2 = Intvec(33);
cout << "ended assigning rvalue...\n";
int &&x = 10;
int aa = 10;
int &a = aa;
x = 100;
cout << "&&x " << &x << x << "\n";
}
template<class T>
void myswap(T &a, T &b) {
T tmp{std::move(a)}; // invokes move constructor
a = std::move(b); // invokes move assignment
b = std::move(tmp); // invokes move assignment
}
//值传递
void change1(int n) {
cout << "值传递--函数操作地址" << &n << endl; //显示的是拷贝的地址而不是源地址
n++;
}
//引用传递
void change2(int &n) {
cout << "引用传递--函数操作地址" << &n << endl;
n++;
}
//指针传递
void change3(int *n) {
cout << "指针传递--函数操作地址 " << n << endl;
*n = *n + 1;
}
int test_point() {
int n = 10;
cout << "实参的地址" << &n <<
endl;
change1(n);
cout << "after change1() n=" << n <<
endl;
change2(n);
cout << "after change2() n=" << n <<
endl;
change3(&n);
cout << "after change3() n=" << n <<
endl;
return true;
}
//值传递
void change1_array(int n) {
cout << "值传递--函数操作地址" << &n << endl; //显示的是拷贝的地址而不是源地址
n++;
}
//指针传递
void change3_array(int *n) {
cout << "指针传递--函数操作地址 " << n << endl;
*n = *n + 1;
}
int test_point_array() {
int *n = new int[3];
n[0] = 10;
n[1] = 20;
int valInt[4] = {0};
valInt[0] = 10;
valInt[1] = 20;
// cout << "实参的地址" << &n << endl;
// change1_array(n);
// cout << "after change1() n=" << n <<
// endl;
cout << "after change2() n=" << n <<
endl;
change3_array(n);
cout << "after change3() n=" << n <<
endl;
return true;
}
void swap(TestCase &testCase1, TestCase &testCase2) {
TestCase *case1 = &testCase1;
TestCase *case2 = &testCase2;
std::cout << "Hello, World! testCase1 " << case1->chars << case1 << &case1 << std::endl;
std::cout << "Hello, World! testCase2 " << case2->chars << case2 << &case2 << std::endl;
printf("\n %p %p \n", &case1, case1);
printf("\n %p %p \n", &case2, case2);
TestCase *temp = case1;
case1 = case2;
case2 = temp;
std::cout << "Hello, World! testCase1 " << case1->chars << case1 << &case1 << std::endl;
std::cout << "Hello, World! testCase2 " << case2->chars << case2 << &case2 << std::endl;
printf("\n %p %p \n", &case1, case1);
printf("\n %p %p \n", &case2, case2);
}
void split(std::string &str, char *separator, bool allow_empty_entries,
std::vector<std::string> &result) {
result.clear();
size_t start_pos = 0;
size_t end_pos;
while ((end_pos = str.find(separator, start_pos)) != std::string::npos) {
if (allow_empty_entries || start_pos != end_pos)
result.push_back(str.substr(start_pos, end_pos - start_pos));
start_pos = end_pos + 1;
}
if (allow_empty_entries || start_pos != str.length())
result.push_back(str.substr(start_pos));
}
void SplitStringHelper(std::string &str, std::unordered_set<std::string> &set) {
std::vector<std::string> substrings;
split(str, " ", false, substrings);
for (size_t i = 0; i < substrings.size(); ++i)
set.insert(substrings[i]);
}
//引用是给编译器看的。可以看做是,经过编译器,又被转化为了指针。引用的好处是不用->箭头符号。并且引用不用主动delete释放。
void printString1(string &msg) {
printf("\n %s %p", msg.data(), &msg);
}
//会重新copy实例的。
void printString2(string msg) {
printf("\n %s %p", msg.data(), &msg);
}
void printString3(string *msg) {
printf("\n %s %p", msg->data(), msg);
}
void printString4(const char &msg) {
//前后地址一致
printf("\n %c %p", msg, &msg);
}
include <iostream> // std::cout
include <thread> // std::thread, std::this_thread::sleep_for
include <chrono> // std::chrono::seconds
void pause_thread(int n) {
std::this_thread::sleep_for(std::chrono::seconds(n));
std::cout << "pause of " << n << " seconds ended\n";
}
int main_fn() {
std::cout << "Spawning and detaching 3 threads...\n";
std::thread thread1(pause_thread, 2);
// std::thread(pause_thread, 2);
// std::thread(pause_thread, 3);
std::cout << "Done spawning threads.\n";
std::cout << "(the main thread will now pause for 5 seconds)\n";
// give the detached threads time to finish (but not guaranteed!):
pause_thread(1);
thread1.join();
return 0;
}
std::mutex mtx; // mutex for critical section
void print_block(int n, char c) {
// critical section (exclusive access to std::cout signaled by lifetime of lck):
std::unique_lock<std::mutex> lck(mtx);
// std::unique_lock<std::mutex> lck(mtx, std::defer_lock);
for (int i = 0; i < n; ++i) { std::cout << c; }
std::cout << '\n';
}
int main_fn2() {
std::atomic<bool> ready(false);
std::atomic_flag winner = ATOMIC_FLAG_INIT;
winner.test_and_set();
std::thread th1(print_block, 50, '*');
std::thread th2(print_block, 50, '$');
std::thread th3(print_block, 50, '0');
std::thread th4(print_block, 50, '1');
th1.join();
th2.join();
th3.join();
th4.join();
return 0;
}
include <mutex> // std::mutex, std::unique_lock
include <condition_variable> // std::condition_variable
std::condition_variable cv;
bool ready = false;
std::mutex prit;
void print_id(int id) {
// std::unique_lock<std::mutex> ptr_lck(prit, std::defer_lock);
// ptr_lck.lock();
// std::cout << "thread bef " << id << '\n';
// ptr_lck.unlock();
std::unique_lock<std::mutex> lck(mtx);
std::cout << "thread bef wait " << id << '\n';
while (!ready) cv.wait(lck);
// ...
std::cout << "thread aft wait" << id << '\n';
}
void go() {
std::unique_lock<std::mutex> lck(mtx);
ready = true;
cv.notify_all();
}
/**
可以看到 thread bef wait 、 thread aft wait 串行打印的,没有发生不安全问题。
-
进lck内,是线程安全的。走到wait后释放锁,等待notify,在竞争获取锁,还是线程安全的。
*/
int main_fn3() {
std::thread threads[10];
// spawn 10 threads:
for (int i = 0; i < 10; ++i)
threads[i] = std::thread(print_id, i);pause_thread(1);
// std::cout << "pause_thread(1) 10 threads ready to race...\n";
go(); // go!for (auto &th : threads) th.join();
return 0;
}
int cargo = 0;
bool shipment_available() { return cargo != 0; }
void consume(int n) {
for (int i = 0; i < n; ++i) {
std::unique_lock<std::mutex> lck(mtx);
//while (!pred()) wait(lck);
cv.wait(lck, shipment_available);
// consume:
std::cout << cargo << '\n';
cargo = 0;
}
}
/**
- 生产和消费的先后顺序不确定,先notify_one 后 wait,导致无法被唤醒。
*/
int main_fn4() {
std::thread consumer_thread(consume, 10);
// pause_thread(1);
// produce 10 items when needed:
for (int i = 0; i < 10; ++i) {
while (shipment_available()) std::this_thread::yield();
std::unique_lock<std::mutex> lck(mtx);
cargo = i + 1;
cv.notify_one();
}
consumer_thread.join();
return 0;
}
int value;
void read_value() {
std::cin >> value;
cv.notify_one();
}
int main_fn5() {
std::cout << "Please, enter an integer (I'll be printing dots): \n";
std::thread th(read_value);
std::mutex mtx;
std::unique_lock<std::mutex> lck(mtx);
while (cv.wait_for(lck, std::chrono::seconds(1)) == std::cv_status::timeout) {
std::cout << '.' << std::endl;
}
std::cout << "You entered: " << value << '\n';
th.join();
return 0;
}
/**
- 返回一个std::shared_ptr 也走move,走copy的情况下use_count加1
- 返回一个std::unique_ptr 走的move
*/
std::shared_ptr<int> returnOneInt() {
std::shared_ptr<int> bar(new int(1099));
return bar;
}
int main_fn6() {
std::shared_ptr<int> foo;
std::shared_ptr<int> bar(new int(10));
foo = bar; // copy
std::cout << "use_count" << bar.use_count() << '\n';
std::cout << "use_count" << foo.use_count() << '\n';
bar = std::make_shared<int>(20); // move
std::cout << "use_count" << bar.use_count() << '\n';
std::cout << "use_count" << foo.use_count() << '\n';
std::cout << "*foo: " << *foo << '\n';
std::cout << "*bar: " << *bar << '\n';
std::unique_ptr<int> unique(new int(30));
std::unique_ptr<int> unique2(new int(30));
foo = std::move(unique); // move from unique_ptr
std::cout << "*foo: " << *foo << '\n';
std::cout << "*bar: " << *bar << '\n';
foo = returnOneInt();
std::cout << "use_count" << foo.use_count() << '\n';
std::cout << "*foo: " << *foo << '\n';
return 0;
}
//只有基类中被定义为 virtual 的方法,才会被虚函数表管理,最终表现出多态的特性~否则是没有的而Java默认都走多态
class AA {
private:
char *count = "data AA";
public:
AA() { cout << "\n ---构造AA-" << this << "-\n"; };
~AA() { cout << "\n ---~析构AA-" << this << "-\n"; };
AA(AA &&A) {
printf("AA move constructor && ");
}
AA &operator=(AA &&other) {
printf("AA move assignment operator && %p", this);
return *this;
}
void fun1() {
cout << "\n ---AA fun1--\n";
};
void fun2() {
cout << "\n ---AA fun2--\n";
};
char *data() {
return count;
};
};
AA createAA() {
AA a;
return a;
}
void processAA(char *data) {
printf("processAA %s", data);
}
//验证 智能指针已重载 == 运算符 nullptr
void testAA() {
{
cout << "\n ---AA S--\n";
processAA(createAA().data());
cout << "\n ---AA E--\n";
}
cout << "\n ---AA EEE--\n";
shared_ptr<AA> adb_weak_shared;
std::weak_ptr<AA> adb_weak;
{
auto adb = std::make_shared<AA>();
adb_weak = adb;
if (adb_weak.lock() == nullptr) {
cout << "\n ---AA adb_weak_shared is null--\n";
}
if (adb_weak.lock() != nullptr) {
cout << "\n ---AA adb_weak_shared not null--\n";
}
if (adb_weak.lock()) {
cout << "\n ---AA adb_weak_shared not null--\n";
}
cout << "\n ---AA adb_weak_shared inner--\n";
}
adb_weak_shared = adb_weak.lock();
if (adb_weak.lock() == nullptr) {
cout << "\n ---AA adb_weak_shared is null--\n";
}
if (adb_weak.lock() != nullptr) {
cout << "\n ---AA adb_weak_shared not null--\n";
}
if (adb_weak.lock()) {
cout << "\n ---AA adb_weak_shared not null--\n";
}
};
class BB : virtual public AA {
public:
~BB() {
}
void fun1() {
cout << "\n ---BB--\n";
};
void fun2() {
cout << "\n ---BB fun2--\n";
};
};
typedef void (*my_fun_lambda)(int);
class TestLambda {
public:
std::weak_ptr<AA> weak;
void testLambda() {
cout << "\n ---testLambda--\n";
std::function<void(int)> function1;
{
auto shared = std::shared_ptr<AA>(new AA());
// std::weak_ptr<AA> weak = shared;
weak = shared;
printf("input :%d before weak=%p %i \n", 0, &weak, weak.lock() != nullptr);
// auto lambda1 = [this](int in) {
// printf("input :%d run weak=%p %i \n", in, &weak, weak.lock() != nullptr);
// };
auto lambda1 = [weak2 = weak](int in) {
printf("input :%d run weak=%p %i \n", in, &weak2, weak2.lock() != nullptr);
};
function1 = lambda1;
// cout << "\n ---testLambda {end}--\n";
function1(10);
}
function1(10);
}
};
typedef struct {
struct {
float r, g, b, a;
} rgba;
float components[4];
} GColorRGBA;
typedef int (*my_fun)();
/**
- made mymap['b'] = AA(); 如果不手动处理&&,则存在构造两次走等号赋值copy的问题。
- mymap['b']会创建一份。AA()也要创建一份。
/
void test_map() {
std::map<char, AA> mymap;
mymap['a'].fun1();
cout << "map 自动创建对象--\n";
mymap['b'] = AA();
/*- ---构造AA-0x7ffeebcbb498-
- ---构造AA-0x7ff009405a88-
- ---~析构AA-0x7ffeebcbb498-
*/
cout << "map 手动创建对象1--\n";
mymap['b'].fun2();
cout << "map 手动创建对象2--\n";
}
int main() {
// GColorRGBA A = GColorRGBA({0, 0, 0, 0});
// GColorRGBA B = GColorRGBA({{0.0f / 255, 0.0f / 255, 0.0f / 255, 1.0f}});
{
main_fn6();
}
{
//:bad_weak_ptr: bad_weak_ptr
// A *a = new A();
// a->getSharedPtr();
}
if (true) {
return 0;
}
test_map();
testAA();
TestLambda testLambda;
testLambda.testLambda();
if (true) {
return 0;
}
// main_fn();
// main_fn2();
// main_fn3();
// main_fn4();
// main_fn5();
{
// my_fun fun_1 = main_fn;
void *aaaa = (void *) (main_fn);
printf("main_fn : %p %p %p \n", main_fn, &main_fn, aaaa);
AA *aa = new AA();
BB *bb = new BB();
//
AA aa_Obj;
BB bb_Obj;
//
printf("test for virtual :%d %d ", sizeof(aa_Obj), sizeof(bb_Obj));
//
AA *aaa = (AA *) (bb);
aaa->fun1();
}
{
cout << "\n ---0--\n";
ReferenceIntvec *referenceIntvec;
{
cout << "\n ---00--\n";
Intvec intvec(10);
cout << "\n ---1--\n";
referenceIntvec = test_referenceIntvec(intvec);
cout << "\n ---2--\n";
}
cout << "\n ---3--\n";
cout << referenceIntvec->getSize() << " 已经销毁了还能调用么--\n";
cout << "\n --4---\n";
}
cout << "\n ---5--\n";
main_fn6();
test_point();
swap_string();
shared_ptr<A> sp1;
{
cout << "\n ---test enable_shared_from_this--\n";
shared_ptr<A> a(new A());
sp1 = a->getSharedPtr();
cout << sp1.use_count() << "-----";
}
sp1->f();
cout << sp1.use_count() << "-----";
{
shared_ptr<C> sp_c;
if (sp_c == nullptr) {
cout << "\n -- sp_c is Empty-\n";
} else {
cout << "\n -- sp_c is not Empty-\n";
}
if (sp_c != nullptr) {
cout << "\n -- sp_c1 is not Empty-\n";
} else {
cout << "\n -- sp_c1 is Empty-\n";
}
unique_ptr<C> uni_c;
if (uni_c == nullptr) {
cout << "\n -- uni_c is Empty-\n";
} else {
cout << "\n -- uni_c is not Empty-\n";
}
long abc = 0;
auto abc_obj = (char *) abc;
if (abc_obj == 0 || abc_obj == nullptr) {
cout << "\n -- abc_obj is null-\n";
} else {
cout << "\n -- uni_c is not Empty-\n";
}
sp_c = std::make_shared<C>("abc");
// shared_ptr<C> sp_cc = sp_c;
{
cout << "\n -- reset before -\n";
sp_c.reset();
cout << "\n -- reset after -\n";
}
cout << "\n -- end -\n";
}
if (true) {
return 0;
}
cout << "\n ------- \n";
Intvec intvec(10);
modify_intvec(&intvec);
printf("\nIntvec %d %d \n", intvec.m_data[0], intvec.m_data[1]);
test_reference();
printf("\n\n");
std::string poiS1;
{
char *poi1 = "1234";
std::string *poiS3 = new std::string("12345678");
const char *poi = poiS3->c_str();
poiS1 = std::string(poiS3->c_str());
printf("\n 是个空么0: %p %p %p\n", poi1, poi, poiS1.data());
delete poiS3;
printf("\n 是个空么1: %s %s \n", poi, poi1);
printf("\n 是个空么3: %s poi1:%s \n", poi, poi1);
}
printf("\n 是个空么2: %s \n", poiS1.data());
// char *poi = "1234";
// std::string poiS1(poi);
// std::string poiS2(poi);
// printf("\n %s,%s,%s\n", poiS2.data(), poiS1.data(), poi);
// delete[] poi;
// printf("\n %s,%s \n", poiS2.data(), poiS1.data());
//
std::string abc("1abc defg abc defg234 ");
std::string *abcP = &abc;
abc = abc + "5697";
const char *temp = abc.data();
printf("\n %c,%c,%p,%p,%p \n", temp[2], *(temp + 2), temp, abcP, &abc);
//b,b,0x7febd1402c10,0x7ffee7799740,0x7ffee7799740
//在栈中的指针自身的地址,指针内的内容也就是堆地址,堆地址中的内容。
printf("\n %p,%p,%c \n", &temp, temp, *temp);
// 1 0x7febd1402c10
printString4((*temp));
// 1 0x7febd1402c10
printString1(abc);
printString2(abc);
printString3(&abc);
std::string *def = new string("2abc defg 123 ");
string(def->data());
printString1(*def);
printString3(def);
delete (def);
//如何看是否野指针
int *inttemp = new int[10];
printf("\n %p %s", def, def->data());
std::unordered_set<std::string> myset;
SplitStringHelper(abc, myset);
std::cout << "\n" << myset.size();
std::cout << " myset contains:";
for (const std::string &x: myset) std::cout << " " << x;
std::cout << std::endl;
char *string1 = "abc";
std::unordered_set<std::string>::const_iterator got = myset.find(string1);
if (got == myset.end())
std::cout << "not found in myset";
else
std::cout << *got << " is in myset";
std::cout << std::endl;
// auto *gl3TestCase = new GL3TestCase();
TestCase *testCase = new TestCase();
TestCase *testCase4 = new TestCase();
// TestCase *testCase = dynamic_cast<tcu::TestCase >(gl3TestCase);
testCase->setChars("000000");
testCase->resetGLContext();
testCase4->setChars("444444");
swap(testCase, *testCase4);
std::cout << "Hello, World! " << typeid(*testCase).name() << std::endl;
char *chars1 = "1234";
char *chars2 = "56789";
chars2 = &(*chars1);
TestCase testCase1;
TestCase testCase2;
testCase1.setChars("1111");
testCase2.setChars("222222");
std::cout << "Hello, World! testCase1 " << testCase1.chars << &testCase1 << std::endl;
std::cout << "Hello, World! testCase2 " << testCase2.chars << &testCase2 << std::endl;
swap(testCase1, testCase2);
std::cout << "Hello, World! testCase1 " << testCase1.chars << &testCase1 << std::endl;
std::cout << "Hello, World! testCase2 " << testCase2.chars << &testCase2 << std::endl;
std::cout << "Hello, World! " << chars2 << &(*(&chars1)) << (&chars1) << std::endl;
return 0;
}