Skip to content

Commit 3ab310f

Browse files
committed
throw exception when initializer list is longer than the size of the array
1 parent e7f77fc commit 3ab310f

File tree

2 files changed

+203
-181
lines changed

2 files changed

+203
-181
lines changed

Aligned.hpp

+167-151
Original file line numberDiff line numberDiff line change
@@ -1,152 +1,168 @@
1-
#ifndef ALIGNED_HPP_INCLUDED
2-
#define ALIGNED_HPP_INCLUDED
3-
4-
#include <cstddef>
5-
#include <cstdint>
6-
#include <initializer_list>
7-
#include <memory>
8-
#include <type_traits>
9-
10-
#include "AlignedBase.hpp"
11-
#include "AlignedArrayConstructorCaller.hpp"
12-
#include "AlignedArrayDestructorCaller.hpp"
13-
14-
#define ALIGNED_BYTES_SIZE(alignment, sizeOfTPaddedToAlignment) (alignment + sizeOfTPaddedToAlignment - 1)
15-
#define ALIGNED_POINTER(T, bytes, sizeOfTPaddedToAlignment) (reinterpret_cast<T *>(uintptr_t(bytes) + (sizeOfTPaddedToAlignment - 1) & ~uintptr_t(sizeOfTPaddedToAlignment - 1)))
16-
#define ALIGNED_ARRAY_BYTES_SIZE(T, sizeOfTPaddedToAlignment, size) (sizeof(T) + (sizeOfTPaddedToAlignment * size) - 1)
17-
#define ALIGNED_ARRAY_INDEX_POINTER(T, pFirstElement, sizeOfTPaddedToAlignment, index) (reinterpret_cast<T *>(uintptr_t(pFirstElement) + (sizeOfTPaddedToAlignment * index)))
18-
19-
template<typename T, std::size_t Alignment = -1>
20-
class Aligned : AlignedBase<T, Alignment> {
21-
uint8_t bytes[ALIGNED_BYTES_SIZE(Alignment, sizeOfTPaddedToAlignment)];
22-
T * const pValue;
23-
Aligned(Aligned const &);
24-
Aligned const & operator=(Aligned const &);
25-
public:
26-
template<typename... Args>
27-
Aligned(Args &&... args) : pValue(ALIGNED_POINTER(T, bytes, sizeOfTPaddedToAlignment)) { new (pValue)T(std::forward<Args>(args)...); }
28-
~Aligned() { pValue->T::~T(); }
29-
T & Ref() { return *pValue; }
30-
T const & Ref() const { return *pValue; }
31-
};
32-
33-
template<typename T>
34-
class Aligned<T, -1> : AlignedBase<T, -1> {
35-
std::unique_ptr<uint8_t[]> const pBytes;
36-
T * const pValue;
37-
public:
38-
template<typename... Args>
39-
Aligned(std::size_t alignment, Args &&... args) : AlignedBase(alignment)
40-
, pBytes(new uint8_t[ALIGNED_BYTES_SIZE(alignment, sizeOfTPaddedToAlignment)])
41-
, pValue(ALIGNED_POINTER(T, pBytes.get(), sizeOfTPaddedToAlignment))
42-
{
43-
new (pValue)T(std::forward<Args>(args)...);
44-
}
45-
~Aligned() { pValue->T::~T(); }
46-
T & Ref() { return *pValue; }
47-
T const & Ref() const { return *pValue; }
48-
};
49-
50-
template<typename T, std::size_t Size, std::size_t Alignment>
51-
class Aligned<T[Size], Alignment> : AlignedBase<T, Alignment> {
52-
Aligned(Aligned const &);
53-
Aligned & operator=(Aligned const &);
54-
static std::size_t const size = Size;
55-
uint8_t bytes[ALIGNED_ARRAY_BYTES_SIZE(T, sizeOfTPaddedToAlignment, Size)];
56-
T * const pFirstElement;
57-
T & element(std::size_t index) { return *ALIGNED_ARRAY_INDEX_POINTER(T, pFirstElement, sizeOfTPaddedToAlignment, index); }
58-
public:
59-
Aligned()
60-
: pFirstElement(ALIGNED_POINTER(T, bytes, sizeOfTPaddedToAlignment))
61-
{
62-
AlignedArrayConstructorCaller<T>::Call(size, pFirstElement, sizeOfTPaddedToAlignment);
63-
}
64-
Aligned(std::initializer_list<T> const & list)
65-
: pFirstElement(ALIGNED_POINTER(T, bytes, sizeOfTPaddedToAlignment))
66-
{
67-
int i = 0;
68-
for (auto it = list.begin(); it != list.end(); ++it)
69-
this->element(i++) = *it;
70-
}
71-
~Aligned() {
72-
AlignedArrayDestructorCaller<T>::Call(size, pFirstElement, sizeOfTPaddedToAlignment);
73-
}
74-
T & operator[](std::size_t index) { return element(index); }
75-
T const & operator[](std::size_t index) const { return element(index); }
76-
std::size_t Size() const { return size; }
77-
};
78-
79-
template<typename T, std::size_t Alignment>
80-
class Aligned<T[], Alignment> : AlignedBase<T, Alignment> {
81-
Aligned(Aligned const &);
82-
Aligned & operator=(Aligned const &);
83-
std::size_t const size;
84-
std::unique_ptr<uint8_t[]> const pBytes;
85-
T * const pFirstElement;
86-
T & element(std::size_t index) { return *ALIGNED_ARRAY_INDEX_POINTER(T, pFirstElement, sizeOfTPaddedToAlignment, index); }
87-
public:
88-
Aligned(std::size_t size)
89-
: size(size)
90-
, pBytes(new uint8_t[ALIGNED_ARRAY_BYTES_SIZE(T, sizeOfTPaddedToAlignment, size)])
91-
, pFirstElement(ALIGNED_POINTER(T, pBytes.get(), sizeOfTPaddedToAlignment))
92-
{
93-
AlignedArrayConstructorCaller<T>::Call(size, pFirstElement, sizeOfTPaddedToAlignment);
94-
}
95-
Aligned(std::initializer_list<T> const & list)
96-
: pFirstElement(ALIGNED_POINTER(T, bytes, sizeOfTPaddedToAlignment))
97-
{
98-
int i = 0;
99-
for (auto it = list.begin(); it != list.end(); ++it)
100-
this->element(i++) = *it;
101-
}
102-
~Aligned() {
103-
AlignedArrayDestructorCaller<T>::Call(size, pFirstElement, sizeOfTPaddedToAlignment);
104-
}
105-
T & operator[](std::size_t index) { return element(index); }
106-
T const & operator[](std::size_t index) const { return element(index); }
107-
std::size_t Size() const { return size; }
108-
};
109-
110-
template<typename T>
111-
class Aligned<T[], -1> : AlignedBase<T, -1> {
112-
Aligned(Aligned const &);
113-
Aligned & operator=(Aligned const &);
114-
std::size_t const size;
115-
std::unique_ptr<uint8_t[]> const pBytes;
116-
T * const pFirstElement;
117-
Aligned();
118-
protected:
119-
T & element(std::size_t index) { return *ALIGNED_ARRAY_INDEX_POINTER(T, pFirstElement, sizeOfTPaddedToAlignment, index); }
120-
public:
121-
Aligned(std::size_t alignment, std::size_t size)
122-
: AlignedBase<T, -1>(alignment)
123-
, size(size)
124-
, pBytes(new uint8_t[ALIGNED_ARRAY_BYTES_SIZE(T, sizeOfTPaddedToAlignment, size)])
125-
, pFirstElement(ALIGNED_POINTER(T, pBytes.get(), sizeOfTPaddedToAlignment))
126-
{
127-
AlignedArrayConstructorCaller<T>::Call(size, pFirstElement, sizeOfTPaddedToAlignment);
128-
}
129-
Aligned(std::size_t alignment, std::initializer_list<T> const & list)
130-
: AlignedBase<T, -1>(alignment)
131-
, size(list.size())
132-
, pBytes(new uint8_t[ALIGNED_ARRAY_BYTES_SIZE(T, sizeOfTPaddedToAlignment, size)])
133-
, pFirstElement(ALIGNED_POINTER(T, pBytes.get(), sizeOfTPaddedToAlignment))
134-
{
135-
int i = 0;
136-
for (auto it = list.begin(); it != list.end(); ++it)
137-
this->element(i++) = *it;
138-
}
139-
~Aligned() {
140-
AlignedArrayDestructorCaller<T>::Call(size, pFirstElement, sizeOfTPaddedToAlignment);
141-
}
142-
T & operator[](std::size_t index) { return element(index); }
143-
T const & operator[](std::size_t index) const { return element(index); }
144-
std::size_t Size() const { return size; }
145-
};
146-
147-
#undef ALIGNED_BYTES_SIZE
148-
#undef ALIGNED_POINTER
149-
#undef ALIGNED_ARRAY_BYTES_SIZE
150-
#undef ALIGNED_ARRAY_INDEX_POINTER
151-
1+
#ifndef ALIGNED_HPP_INCLUDED
2+
#define ALIGNED_HPP_INCLUDED
3+
4+
#include <cstddef>
5+
#include <cstdint>
6+
#include <initializer_list>
7+
#include <memory>
8+
#include <type_traits>
9+
10+
#include "AlignedBase.hpp"
11+
#include "AlignedArrayConstructorCaller.hpp"
12+
#include "AlignedArrayDestructorCaller.hpp"
13+
#include "InitializerListLongerThanSizeException.hpp"
14+
15+
#define ALIGNED_BYTES_SIZE(alignment, sizeOfTPaddedToAlignment) (alignment + sizeOfTPaddedToAlignment - 1)
16+
#define ALIGNED_POINTER(T, bytes, sizeOfTPaddedToAlignment) (reinterpret_cast<T *>(uintptr_t(bytes) + (sizeOfTPaddedToAlignment - 1) & ~uintptr_t(sizeOfTPaddedToAlignment - 1)))
17+
#define ALIGNED_ARRAY_BYTES_SIZE(T, sizeOfTPaddedToAlignment, size) (sizeof(T) + (sizeOfTPaddedToAlignment * size) - 1)
18+
#define ALIGNED_ARRAY_INDEX_POINTER(T, pFirstElement, sizeOfTPaddedToAlignment, index) (reinterpret_cast<T *>(uintptr_t(pFirstElement) + (sizeOfTPaddedToAlignment * index)))
19+
20+
template<typename T, std::size_t Alignment = -1>
21+
class Aligned : AlignedBase<T, Alignment> {
22+
uint8_t bytes[ALIGNED_BYTES_SIZE(Alignment, sizeOfTPaddedToAlignment)];
23+
T * const pValue;
24+
Aligned(Aligned const &);
25+
Aligned const & operator=(Aligned const &);
26+
public:
27+
template<typename... Args>
28+
Aligned(Args &&... args) : pValue(ALIGNED_POINTER(T, bytes, sizeOfTPaddedToAlignment)) { new (pValue)T(std::forward<Args>(args)...); }
29+
~Aligned() { pValue->T::~T(); }
30+
T & Ref() { return *pValue; }
31+
T const & Ref() const { return *pValue; }
32+
};
33+
34+
template<typename T>
35+
class Aligned<T, -1> : AlignedBase<T, -1> {
36+
std::unique_ptr<uint8_t[]> const pBytes;
37+
T * const pValue;
38+
public:
39+
template<typename... Args>
40+
Aligned(std::size_t alignment, Args &&... args) : AlignedBase(alignment)
41+
, pBytes(new uint8_t[ALIGNED_BYTES_SIZE(alignment, sizeOfTPaddedToAlignment)])
42+
, pValue(ALIGNED_POINTER(T, pBytes.get(), sizeOfTPaddedToAlignment))
43+
{
44+
new (pValue)T(std::forward<Args>(args)...);
45+
}
46+
~Aligned() { pValue->T::~T(); }
47+
T & Ref() { return *pValue; }
48+
T const & Ref() const { return *pValue; }
49+
};
50+
51+
template<typename T, std::size_t Size, std::size_t Alignment>
52+
class Aligned<T[Size], Alignment> : AlignedBase<T, Alignment> {
53+
Aligned(Aligned const &);
54+
Aligned & operator=(Aligned const &);
55+
static std::size_t const size = Size;
56+
uint8_t bytes[ALIGNED_ARRAY_BYTES_SIZE(T, sizeOfTPaddedToAlignment, Size)];
57+
T * const pFirstElement;
58+
T & element(std::size_t index) { return *ALIGNED_ARRAY_INDEX_POINTER(T, pFirstElement, sizeOfTPaddedToAlignment, index); }
59+
public:
60+
Aligned()
61+
: pFirstElement(ALIGNED_POINTER(T, bytes, sizeOfTPaddedToAlignment))
62+
{
63+
AlignedArrayConstructorCaller<T>::Call(size, pFirstElement, sizeOfTPaddedToAlignment);
64+
}
65+
Aligned(std::size_t size, std::initializer_list<T> const & list)
66+
: pFirstElement(ALIGNED_POINTER(T, bytes, sizeOfTPaddedToAlignment))
67+
{
68+
if (size < list.size())
69+
throw InitializerListLongerThanSizeException();
70+
int i = 0;
71+
for (auto it = list.begin(); it != list.end(); ++it)
72+
this->element(i++) = *it;
73+
}
74+
Aligned(std::initializer_list<T> const & list)
75+
: Aligned(list.size(), list)
76+
{}
77+
~Aligned() {
78+
AlignedArrayDestructorCaller<T>::Call(size, pFirstElement, sizeOfTPaddedToAlignment);
79+
}
80+
T & operator[](std::size_t index) { return element(index); }
81+
T const & operator[](std::size_t index) const { return element(index); }
82+
std::size_t Size() const { return size; }
83+
};
84+
85+
template<typename T, std::size_t Alignment>
86+
class Aligned<T[], Alignment> : AlignedBase<T, Alignment> {
87+
Aligned(Aligned const &);
88+
Aligned & operator=(Aligned const &);
89+
std::size_t const size;
90+
std::unique_ptr<uint8_t[]> const pBytes;
91+
T * const pFirstElement;
92+
T & element(std::size_t index) { return *ALIGNED_ARRAY_INDEX_POINTER(T, pFirstElement, sizeOfTPaddedToAlignment, index); }
93+
public:
94+
Aligned(std::size_t size)
95+
: size(size)
96+
, pBytes(new uint8_t[ALIGNED_ARRAY_BYTES_SIZE(T, sizeOfTPaddedToAlignment, size)])
97+
, pFirstElement(ALIGNED_POINTER(T, pBytes.get(), sizeOfTPaddedToAlignment))
98+
{
99+
AlignedArrayConstructorCaller<T>::Call(size, pFirstElement, sizeOfTPaddedToAlignment);
100+
}
101+
Aligned(std::size_t size, std::initializer_list<T> const & list)
102+
: pFirstElement(ALIGNED_POINTER(T, bytes, sizeOfTPaddedToAlignment))
103+
{
104+
if (size < list.size())
105+
throw InitializerListLongerThanSizeException();
106+
int i = 0;
107+
for (auto it = list.begin(); it != list.end(); ++it)
108+
this->element(i++) = *it;
109+
}
110+
Aligned(std::initializer_list<T> const & list)
111+
: Aligned(list.size(), list)
112+
{}
113+
~Aligned() {
114+
AlignedArrayDestructorCaller<T>::Call(size, pFirstElement, sizeOfTPaddedToAlignment);
115+
}
116+
T & operator[](std::size_t index) { return element(index); }
117+
T const & operator[](std::size_t index) const { return element(index); }
118+
std::size_t Size() const { return size; }
119+
};
120+
121+
template<typename T>
122+
class Aligned<T[], -1> : AlignedBase<T, -1> {
123+
Aligned(Aligned const &);
124+
Aligned & operator=(Aligned const &);
125+
std::size_t const size;
126+
std::unique_ptr<uint8_t[]> const pBytes;
127+
T * const pFirstElement;
128+
Aligned();
129+
protected:
130+
T & element(std::size_t index) { return *ALIGNED_ARRAY_INDEX_POINTER(T, pFirstElement, sizeOfTPaddedToAlignment, index); }
131+
public:
132+
Aligned(std::size_t alignment, std::size_t size)
133+
: AlignedBase<T, -1>(alignment)
134+
, size(size)
135+
, pBytes(new uint8_t[ALIGNED_ARRAY_BYTES_SIZE(T, sizeOfTPaddedToAlignment, size)])
136+
, pFirstElement(ALIGNED_POINTER(T, pBytes.get(), sizeOfTPaddedToAlignment))
137+
{
138+
AlignedArrayConstructorCaller<T>::Call(size, pFirstElement, sizeOfTPaddedToAlignment);
139+
}
140+
Aligned(std::size_t alignment, std::size_t size, std::initializer_list<T> const & list)
141+
: AlignedBase<T, -1>(alignment)
142+
, size(size)
143+
, pBytes(new uint8_t[ALIGNED_ARRAY_BYTES_SIZE(T, sizeOfTPaddedToAlignment, size)])
144+
, pFirstElement(ALIGNED_POINTER(T, pBytes.get(), sizeOfTPaddedToAlignment))
145+
{
146+
if (size < list.size())
147+
throw InitializerListLongerThanSizeException();
148+
int i = 0;
149+
for (auto it = list.begin(); it != list.end(); ++it)
150+
this->element(i++) = *it;
151+
}
152+
Aligned(std::size_t alignment, std::initializer_list<T> const & list)
153+
: Aligned(alignment, list.size(), list)
154+
{}
155+
~Aligned() {
156+
AlignedArrayDestructorCaller<T>::Call(size, pFirstElement, sizeOfTPaddedToAlignment);
157+
}
158+
T & operator[](std::size_t index) { return element(index); }
159+
T const & operator[](std::size_t index) const { return element(index); }
160+
std::size_t Size() const { return size; }
161+
};
162+
163+
#undef ALIGNED_BYTES_SIZE
164+
#undef ALIGNED_POINTER
165+
#undef ALIGNED_ARRAY_BYTES_SIZE
166+
#undef ALIGNED_ARRAY_INDEX_POINTER
167+
152168
#endif

CacheAligned.hpp

+36-30
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,37 @@
1-
#ifndef CACHEALIGNED_HPP_INCLUDED
2-
#define CACHEALIGNED_HPP_INCLUDED
3-
4-
#include <cstddef>
5-
#include <initializer_list>
6-
#include <type_traits>
7-
8-
#include "Aligned.hpp"
9-
#include "CacheAlignedBase.hpp"
10-
11-
template<typename T>
12-
class CacheAligned : public Aligned<T>, CacheAlignedBase<T> {
13-
public:
14-
template<typename... Args>
15-
CacheAligned(Args &&... args) : Aligned(cacheLineSize(), std::forward<Args>(args)...) {}
16-
};
17-
18-
template<typename T>
19-
class CacheAligned<T[]> : public Aligned<T[]>, CacheAlignedBase<T> {
20-
public:
21-
CacheAligned(std::size_t size) : Aligned(cacheLineSize(), size) {}
22-
CacheAligned(std::initializer_list<T> const & list)
23-
: CacheAligned(list.size())
24-
{
25-
int i = 0;
26-
for (auto it = list.begin(); it != list.end(); ++it)
27-
this->element(i++) = *it;
28-
}
29-
};
30-
1+
#ifndef CACHEALIGNED_HPP_INCLUDED
2+
#define CACHEALIGNED_HPP_INCLUDED
3+
4+
#include <cstddef>
5+
#include <initializer_list>
6+
#include <type_traits>
7+
8+
#include "Aligned.hpp"
9+
#include "CacheAlignedBase.hpp"
10+
#include "InitializerListLongerThanSizeException.hpp"
11+
12+
template<typename T>
13+
class CacheAligned : public Aligned<T>, CacheAlignedBase<T> {
14+
public:
15+
template<typename... Args>
16+
CacheAligned(Args &&... args) : Aligned(cacheLineSize(), std::forward<Args>(args)...) {}
17+
};
18+
19+
template<typename T>
20+
class CacheAligned<T[]> : public Aligned<T[]>, CacheAlignedBase<T> {
21+
public:
22+
CacheAligned(std::size_t size) : Aligned(cacheLineSize(), size) {}
23+
CacheAligned(std::size_t size, std::initializer_list<T> const & list)
24+
: CacheAligned(size)
25+
{
26+
if (size < list.size())
27+
throw InitializerListLongerThanSizeException();
28+
int i = 0;
29+
for (auto it = list.begin(); it != list.end(); ++it)
30+
this->element(i++) = *it;
31+
}
32+
CacheAligned(std::initializer_list<T> const & list)
33+
: CacheAligned(list.size(), list)
34+
{}
35+
};
36+
3137
#endif

0 commit comments

Comments
 (0)