Skip to content

Commit 856c318

Browse files
committed
pod
1 parent 6b503ab commit 856c318

5 files changed

Lines changed: 294 additions & 109 deletions

File tree

‎cpp/README.md‎

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,13 @@
3232
1. [explicit](explicit.cpp)
3333
1. [class](class.cpp)
3434
1. Constructor
35-
1. [Most vexing parse](most_vexing_parse.cpp)
36-
1. [Delegating constructor](delegating_constructor.cpp)
37-
1. [Implicitly deleted constructor](implicitly_deleted_constructor.cpp)
38-
1. [Constructor init object member](constructor_init_object_member.cpp)
39-
1. [Initializer list constructor](initializer_list_constructor.cpp)
40-
1. [static](static.cpp)
35+
1. [Most vexing parse](most_vexing_parse.cpp)
36+
1. [Delegating constructor](delegating_constructor.cpp)
37+
1. [Implicitly deleted constructor](implicitly_deleted_constructor.cpp)
38+
1. [Constructor init object member](constructor_init_object_member.cpp)
39+
1. [Initializer list constructor](initializer_list_constructor.cpp)
40+
1. [static](static.cpp)
41+
1. [POD](pod.cpp)
4142
1. Inheritance
4243
1. [Inheritance override](inheritance_override.cpp)
4344
1. [Inherit overload_hide](inherit_overload_hide.cpp)

‎cpp/class.cpp‎

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -910,13 +910,6 @@ int main() {
910910
# Aggregate initialization
911911
912912
http://en.cppreference.com/w/cpp/language/aggregate_initialization
913-
914-
# POD
915-
916-
Plain old data:
917-
918-
https://stackoverflow.com/questions/146452/what-are-pod-types-in-c
919-
http://stackoverflow.com/questions/4178175/what-are-aggregates-and-pods-and-how-why-are-they-special
920913
*/
921914
{
922915
// Syntax with new.

‎cpp/common.hpp‎

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
Prefer `.hpp` which indicates that the header is C++ specific, and not pure C.
1414
*/
1515

16-
#include <atomic>
1716
#include <algorithm> // copy, erase, lower_bound, remove_if, swap, transform
1817
#include <bitset>
1918
#include <exception> // bad_alloc, bad_cast, bad_exception, bad_typeid, exception, ios_base::failure
@@ -29,26 +28,29 @@
2928
#include <numeric> // partial sums, differences on std::vectors of numbers
3029
#include <ostream> // ostream
3130
#include <queue> // priority_queue
32-
#include <ratio> // ratio, nano
33-
#include <random>
3431
#include <set> // multiset, set
3532
#include <string> // getline, string
3633
#include <sstream> // stringstream
3734
#include <typeinfo> // typeid, bad_typeid, bad_typecast
38-
#include <tuple> // tuple
39-
#include <unordered_set>
40-
#include <unordered_map> // unordered_map, unordered_multimap
4135
#include <utility> // forward, get, pair, size_t, type_info, declval
4236
#include <vector> // vector
4337
#include <valarray>
4438

4539
#if __cplusplus >= 201103L
4640
#include <array> // array
41+
#include <atomic>
42+
#include <cassert>
4743
#include <chrono> // nanoseconds
4844
#include <mutex> // mutex
45+
#include <random>
46+
#include <ratio> // ratio, nano
4947
#include <regex> // regex
5048
#include <thread> // thread
49+
#include <tuple>
50+
#include <type_traits> // is_pod, is_trivial, is_trivially_copyable, etc. etc.
5151
#include <typeindex> // type_index
52+
#include <unordered_set>
53+
#include <unordered_map> // unordered_map, unordered_multimap
5254
#endif
5355

5456
/*
@@ -76,11 +78,19 @@
7678
7779
http://stackoverflow.com/questions/32606023/when-using-c-headers-in-c-should-we-use-functions-from-std-or-the-global-na
7880
*/
79-
#include <cassert>
8081
#include <cmath>
8182
#include <cstdlib>
8283
#include <cstring>
8384

85+
// Global thread parameters.
86+
const int NUM_THREADS = 1000;
87+
const int NUM_ITERS = 1000;
88+
const int NUM_OPS = NUM_THREADS * NUM_ITERS;
89+
90+
// Misc.
91+
bool odd(int i){ return (i % 2) == 1; }
92+
93+
#if __cplusplus >= 201103L
8494
// Keeps a list of functions that called it for testing purposes.
8595
std::vector<std::string> callStack;
8696
void printCallStack() {
@@ -90,14 +100,6 @@ void printCallStack() {
90100
std::cout << "END callStack" << std::endl;
91101
}
92102

93-
// Global thread parameters.
94-
const int NUM_THREADS = 1000;
95-
const int NUM_ITERS = 1000;
96-
const int NUM_OPS = NUM_THREADS * NUM_ITERS;
97-
98-
// Misc.
99-
bool odd(int i){ return (i % 2) == 1; }
100-
101103
/**
102104
* Simple instrumented class for tests on constructor destructor order.
103105
*
@@ -177,3 +179,4 @@ class NoBaseNoMember1 {
177179
~NoBaseNoMember1(){callStack.push_back("NoBaseNoMember1::~NoBaseNoMember1()");}
178180
void method(){callStack.push_back("NoBaseNoMember1::method()");}
179181
};
182+
#endif

‎cpp/pod.cpp‎

Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
/* # POD
2+
*
3+
* Plain old data:
4+
*
5+
* - https://en.cppreference.com/w/cpp/named_req/PODType
6+
* - https://stackoverflow.com/questions/146452/what-are-pod-types-in-c
7+
* - http://stackoverflow.com/questions/4178175/what-are-aggregates-and-pods-and-how-why-are-they-special
8+
* - https://github.com/gcc-mirror/gcc/blob/gcc-8_2_0-release/libstdc%2B%2B-v3/testsuite/20_util/is_pod/value.cc a few tests, but nothing awesome
9+
*/
10+
11+
#include <type_traits>
12+
13+
int main() {
14+
/* POD restrictions have become more and more relaxed as the standard evolved.
15+
*
16+
* std::is_pod was added in C++11, so let's consider that standard onwards for now.
17+
*/
18+
#if __cplusplus >= 201103L
19+
/* Non-POD examples. Let's just walk all non-recursive non-POD branches of cppreference. */
20+
{
21+
/* Non-trivial implies non-POD.
22+
* https://en.cppreference.com/w/cpp/named_req/TrivialType
23+
*/
24+
{
25+
/* Not trivial because we removed the default constructor
26+
* by using our own custom non-default constructor.
27+
*/
28+
{
29+
struct C {
30+
C(int i) {}
31+
};
32+
static_assert(std::is_trivially_copyable<C>());
33+
static_assert(!std::is_trivial<C>());
34+
static_assert(!std::is_pod<C>());
35+
}
36+
37+
/* Not trivial because not trivially copyable. */
38+
{
39+
struct C {
40+
C(C& c) {}
41+
};
42+
static_assert(!std::is_trivially_copyable<C>());
43+
static_assert(!std::is_trivial<C>());
44+
static_assert(!std::is_pod<C>());
45+
}
46+
}
47+
48+
/* Non-standard layout implies non-POD.
49+
* https://en.cppreference.com/w/cpp/named_req/StandardLayoutType
50+
*/
51+
{
52+
/* Non static members with different access control:
53+
* i is public and j is private.
54+
*/
55+
{
56+
struct C {
57+
public:
58+
int i;
59+
private:
60+
int j;
61+
};
62+
static_assert(!std::is_standard_layout<C>());
63+
static_assert(!std::is_pod<C>());
64+
}
65+
66+
/* virtual function */
67+
{
68+
struct C {
69+
virtual void f() = 0;
70+
};
71+
static_assert(!std::is_standard_layout<C>());
72+
static_assert(!std::is_pod<C>());
73+
}
74+
75+
/* Non-static member that is reference. */
76+
{
77+
struct C {
78+
int &i;
79+
};
80+
static_assert(!std::is_standard_layout<C>());
81+
static_assert(!std::is_pod<C>());
82+
}
83+
84+
/* Neither:
85+
*
86+
* - has no base classes with non-static data members, or
87+
* - has no non-static data members in the most derived class
88+
* and at most one base class with non-static data members
89+
*/
90+
{
91+
/* Non POD because has two base classes with non-static data members. */
92+
{
93+
struct Base1 {
94+
int i;
95+
};
96+
struct Base2 {
97+
int j;
98+
};
99+
struct C : Base1, Base2 {};
100+
static_assert(!std::is_standard_layout<C>());
101+
static_assert(!std::is_pod<C>());
102+
}
103+
104+
/* POD: has just one base class with non-static member. */
105+
{
106+
struct Base1 {
107+
int i;
108+
};
109+
struct C : Base1 {};
110+
static_assert(std::is_standard_layout<C>());
111+
static_assert(std::is_pod<C>());
112+
}
113+
}
114+
115+
/* Base classes of the same type as the first non-static data member.
116+
* TODO failing on GCC 8.1 -std=c++11, 14 and 17.
117+
*/
118+
{
119+
struct C {};
120+
struct D : C {
121+
C c;
122+
};
123+
//static_assert(!std::is_standard_layout<C>());
124+
//static_assert(!std::is_pod<C>());
125+
};
126+
127+
/* C++14 standard layout new rules, yay! */
128+
{
129+
/* Has two (possibly indirect) base class subobjects of the same type.
130+
* Here C has two base classes which are indirectly "Base".
131+
*
132+
* TODO failing on GCC 8.1 -std=c++11, 14 and 17.
133+
* even though the example was copy pasted from cppreference.
134+
*/
135+
{
136+
struct Q {};
137+
struct S : Q { };
138+
struct T : Q { };
139+
struct U : S, T { }; // not a standard-layout class: two base class subobjects of type Q
140+
//static_assert(!std::is_standard_layout<U>());
141+
//static_assert(!std::is_pod<U>());
142+
}
143+
144+
/* Has all non-static data members and bit-fields declared in the same class
145+
* (either all in the derived or all in some base).
146+
*/
147+
{
148+
struct Base { int i; };
149+
struct Middle : Base {};
150+
struct C : Middle { int j; };
151+
static_assert(!std::is_standard_layout<C>());
152+
static_assert(!std::is_pod<C>());
153+
}
154+
155+
/* None of the base class subobjects has the same type as
156+
* for non-union types, as the first non-static data member
157+
*
158+
* TODO: similar to the C++11 for which we could not make a proper example,
159+
* but with recursivity added.
160+
*/
161+
162+
/* TODO come up with an example that is POD in C++14 but not in C++11. */
163+
}
164+
}
165+
}
166+
167+
/* POD examples. Everything that does not fall in the non-POD examples. */
168+
{
169+
/* Can't get more POD than this. */
170+
{
171+
struct C {};
172+
static_assert(std::is_pod<C>());
173+
}
174+
175+
/* Private member: became POD in C++11
176+
* https://stackoverflow.com/questions/4762788/can-a-class-with-all-private-members-be-a-pod-class/4762944#4762944
177+
*/
178+
{
179+
struct C {
180+
private:
181+
int i;
182+
};
183+
#if __cplusplus >= 201103L
184+
static_assert(std::is_pod<C>());
185+
#else
186+
static_assert(!std::is_pod<C>());
187+
#endif
188+
}
189+
190+
/* Derived.
191+
* https://stackoverflow.com/questions/4762788/can-a-class-with-all-private-members-be-a-pod-class/4762944#4762944
192+
*/
193+
{
194+
struct C {};
195+
struct D : C {};
196+
static_assert(std::is_pod<D>());
197+
}
198+
}
199+
#endif
200+
}

0 commit comments

Comments
 (0)