support bazel complie this project and format code.
This commit is contained in:
27
learn_class/modern_cpp_30/container1/BUILD
Normal file
27
learn_class/modern_cpp_30/container1/BUILD
Normal file
@@ -0,0 +1,27 @@
|
||||
# please run `bazel run //learn_class/modern_cpp_30/container1:container`
|
||||
# please run `bazel run //learn_class/modern_cpp_30/container1:vector_l`
|
||||
|
||||
load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library")
|
||||
|
||||
cc_library(
|
||||
name = "output_container",
|
||||
hdrs = ["output_container.h"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
cc_binary(
|
||||
name = "container",
|
||||
srcs = ["container.cpp"],
|
||||
copts = ["-std=c++17"],
|
||||
deps = [
|
||||
":output_container",
|
||||
],
|
||||
)
|
||||
cc_binary(
|
||||
name = "vector_l",
|
||||
srcs = ["vector_l.cpp"],
|
||||
copts = ["-std=c++17"],
|
||||
deps = [
|
||||
":output_container",
|
||||
],
|
||||
)
|
17
learn_class/modern_cpp_30/container1/container.cpp
Normal file
17
learn_class/modern_cpp_30/container1/container.cpp
Normal file
@@ -0,0 +1,17 @@
|
||||
//
|
||||
// Created by light on 19-12-16.
|
||||
//
|
||||
|
||||
#include "output_container.h"
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main() {
|
||||
map<int, int> mp{{1, 1}, {2, 4}, {3, 9}};
|
||||
cout << mp << endl;
|
||||
vector<vector<int>> vv{{1, 1}, {2, 4}, {3, 9}};
|
||||
cout << vv << endl;
|
||||
}
|
134
learn_class/modern_cpp_30/container1/output_container.h
Normal file
134
learn_class/modern_cpp_30/container1/output_container.h
Normal file
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* Written by Wu Yongwei <wuyongwei AT gmail DOT com>.
|
||||
*
|
||||
* Using this file requires a C++17-compliant compiler.
|
||||
*
|
||||
* This is free and unencumbered software released into the public domain.
|
||||
*
|
||||
* Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
* distribute this software, either in source code form or as a compiled
|
||||
* binary, for any purpose, commercial or non-commercial, and by any
|
||||
* means.
|
||||
*
|
||||
* In jurisdictions that recognize copyright laws, the author or authors
|
||||
* of this software dedicate any and all copyright interest in the
|
||||
* software to the public domain. We make this dedication for the benefit
|
||||
* of the public at large and to the detriment of our heirs and
|
||||
* successors. We intend this dedication to be an overt act of
|
||||
* relinquishment in perpetuity of all present and future rights to this
|
||||
* software under copyright law.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* For more information, please refer to <http://unlicense.org>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef OUTPUT_CONTAINER_H
|
||||
#define OUTPUT_CONTAINER_H
|
||||
|
||||
#include <ostream> // std::ostream
|
||||
#include <type_traits> // std::false_type/true_type/decay_t/is_same_v
|
||||
#include <utility> // std::declval/pair
|
||||
|
||||
// Type trait to detect std::pair
|
||||
template <typename T> struct is_pair : std::false_type {};
|
||||
template <typename T, typename U>
|
||||
struct is_pair<std::pair<T, U>> : std::true_type {};
|
||||
template <typename T> inline constexpr bool is_pair_v = is_pair<T>::value;
|
||||
|
||||
// Type trait to detect whether an output function already exists
|
||||
template <typename T> struct has_output_function {
|
||||
template <class U>
|
||||
static auto output(U *ptr)
|
||||
-> decltype(std::declval<std::ostream &>() << *ptr, std::true_type());
|
||||
template <class U> static std::false_type output(...);
|
||||
static constexpr bool value = decltype(output<T>(nullptr))::value;
|
||||
};
|
||||
template <typename T>
|
||||
inline constexpr bool has_output_function_v = has_output_function<T>::value;
|
||||
/* NB: Visual Studio 2017 (or below) may have problems with
|
||||
* has_output_function_v<T>: you should then use
|
||||
* has_output_function<T>::value instead, or upgrade to
|
||||
* Visual Studio 2019. */
|
||||
|
||||
// Output function for std::pair
|
||||
template <typename T, typename U>
|
||||
std::ostream &operator<<(std::ostream &os, const std::pair<T, U> &pr);
|
||||
|
||||
// Element output function for containers that define a key_type and
|
||||
// have its value type as std::pair
|
||||
template <typename T, typename Cont>
|
||||
auto output_element(std::ostream &os, const T &element, const Cont &,
|
||||
const std::true_type)
|
||||
-> decltype(std::declval<typename Cont::key_type>(), os);
|
||||
// Element output function for other containers
|
||||
template <typename T, typename Cont>
|
||||
auto output_element(std::ostream &os, const T &element, const Cont &, ...)
|
||||
-> decltype(os);
|
||||
|
||||
// Main output function, enabled only if no output function already exists
|
||||
template <typename T, typename = std::enable_if_t<!has_output_function_v<T>>>
|
||||
auto operator<<(std::ostream &os, const T &container)
|
||||
-> decltype(container.begin(), container.end(), os) {
|
||||
using std::decay_t;
|
||||
using std::is_same_v;
|
||||
|
||||
using element_type = decay_t<decltype(*container.begin())>;
|
||||
constexpr bool is_char_v = is_same_v<element_type, char>;
|
||||
if constexpr (!is_char_v) {
|
||||
os << "{ ";
|
||||
}
|
||||
if (!container.empty()) {
|
||||
auto end = container.end();
|
||||
bool on_first_element = true;
|
||||
for (auto it = container.begin(); it != end; ++it) {
|
||||
if constexpr (is_char_v) {
|
||||
if (*it == '\0') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if constexpr (!is_char_v) {
|
||||
if (!on_first_element) {
|
||||
os << ", ";
|
||||
} else {
|
||||
on_first_element = false;
|
||||
}
|
||||
}
|
||||
output_element(os, *it, container, is_pair<element_type>());
|
||||
}
|
||||
}
|
||||
if constexpr (!is_char_v) {
|
||||
os << " }";
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
template <typename T, typename Cont>
|
||||
auto output_element(std::ostream &os, const T &element, const Cont &,
|
||||
const std::true_type)
|
||||
-> decltype(std::declval<typename Cont::key_type>(), os) {
|
||||
os << element.first << " => " << element.second;
|
||||
return os;
|
||||
}
|
||||
|
||||
template <typename T, typename Cont>
|
||||
auto output_element(std::ostream &os, const T &element, const Cont &, ...)
|
||||
-> decltype(os) {
|
||||
os << element;
|
||||
return os;
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
std::ostream &operator<<(std::ostream &os, const std::pair<T, U> &pr) {
|
||||
os << '(' << pr.first << ", " << pr.second << ')';
|
||||
return os;
|
||||
}
|
||||
|
||||
#endif // OUTPUT_CONTAINER_H
|
45
learn_class/modern_cpp_30/container1/vector_l.cpp
Normal file
45
learn_class/modern_cpp_30/container1/vector_l.cpp
Normal file
@@ -0,0 +1,45 @@
|
||||
//
|
||||
// Created by light on 19-12-16.
|
||||
//
|
||||
#include <iostream>
|
||||
#include <queue>
|
||||
#include <vector>
|
||||
using namespace std;
|
||||
|
||||
class Obj1 {
|
||||
public:
|
||||
Obj1() { cout << "Obj1()\n"; }
|
||||
Obj1(const Obj1 &) { cout << "Obj1(const Obj1&)\n"; }
|
||||
Obj1(Obj1 &&) { cout << "Obj1(Obj1&&)\n"; }
|
||||
};
|
||||
|
||||
class Obj2 {
|
||||
public:
|
||||
Obj2() { cout << "Obj2()\n"; }
|
||||
Obj2(const Obj2 &) { cout << "Obj2(const Obj2&)\n"; }
|
||||
Obj2(Obj2 &&) noexcept { cout << "Obj2(Obj2&&)\n"; }
|
||||
};
|
||||
|
||||
int main() {
|
||||
vector<int> v;
|
||||
|
||||
int nums = 20;
|
||||
for (int i = 0; i < nums; ++i) {
|
||||
v.push_back(i + 1);
|
||||
cout << "v_size: " << v.size() << "\t v_capacity: " << v.capacity() << endl;
|
||||
}
|
||||
// 头两个在已有空间上成功构造。第三个时发现空间不足,系统会请求更大的空间,大小由实现决定(比如两倍)。
|
||||
// 有了足够的空间后,就会在新空间的第三个的位置构造(第三个obj1),成功之后再把头两个拷贝或移动过来。
|
||||
vector<Obj1> v1;
|
||||
// v1.reserve(2);
|
||||
v1.emplace_back();
|
||||
v1.emplace_back();
|
||||
v1.emplace_back();
|
||||
v1.emplace_back();
|
||||
|
||||
vector<Obj2> v2;
|
||||
v2.reserve(2);
|
||||
v2.emplace_back();
|
||||
v2.emplace_back();
|
||||
v2.emplace_back();
|
||||
}
|
Reference in New Issue
Block a user