Skip to content

Commit

Permalink
Merge pull request #532 from Bertk/c++11-tests
Browse files Browse the repository at this point in the history
add C++11/C++14 test resources
  • Loading branch information
guwirth committed Jun 16, 2015
2 parents 78f68a4 + 0fa888e commit c18ec78
Show file tree
Hide file tree
Showing 28 changed files with 903 additions and 0 deletions.
8 changes: 8 additions & 0 deletions cxx-squid/src/test/resources/parser/own/C++11/alignas.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// every object of type sse_t will be aligned to 16-byte boundary
struct alignas(16) sse_t
{
float sse_data[4];
};

// the array "cacheline" will be aligned to 128-byte boundary
alignas(128) char cacheline[128];
11 changes: 11 additions & 0 deletions cxx-squid/src/test/resources/parser/own/C++11/alignof.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#include <iostream>
#include <type_traits>

class A {};

int main()
{
std::cout << std::alignment_of<A>::value << '\n';
std::cout << std::alignment_of<int>::value << '\n';
std::cout << std::alignment_of<double>::value << '\n';
}
43 changes: 43 additions & 0 deletions cxx-squid/src/test/resources/parser/own/C++11/alignstorage.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#include <iostream>
#include <type_traits>
#include <string>

template<class T, std::size_t N>
class static_vector
{
// properly aligned uninitialized storage for N T's
typename std::aligned_storage<sizeof(T), alignof(T)>::type data[N];
std::size_t m_size = 0;

public:
// Create an object in aligned storage
template<typename ...Args> void emplace_back(Args&&... args)
{
if (m_size >= N) // possible error handling
throw std::bad_alloc{};
new(data + m_size) T(std::forward<Args>(args)...);
++m_size;
}

// Access an object in aligned storage
const T& operator[](std::size_t pos) const
{
return *reinterpret_cast<const T*>(data + pos);
}

// Delete objects from aligned storage
~static_vector()
{
for (std::size_t pos = 0; pos < m_size; ++pos) {
reinterpret_cast<const T*>(data + pos)->~T();
}
}
};

int main()
{
static_vector<std::string, 10> v1;
v1.emplace_back(5, '*');
v1.emplace_back(10, '*');
std::cout << v1[0] << '\n' << v1[1] << '\n';
}
24 changes: 24 additions & 0 deletions cxx-squid/src/test/resources/parser/own/C++11/array.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#include <string>
#include <iterator>
#include <iostream>
#include <algorithm>
#include <array>

int main()
{
// construction uses aggregate initialization
std::array<int, 3> a1{ { 1, 2, 3 } }; // double-braces required in C++11 (not in C++14)
std::array<int, 3> a2 = { 1, 2, 3 }; // never required after =
std::array<std::string, 2> a3 = { std::string("a"), "b" };

// container operations are supported
std::sort(a1.begin(), a1.end());
std::reverse_copy(a2.begin(), a2.end(),
std::ostream_iterator<int>(std::cout, " "));

std::cout << '\n';

// ranged for loop is supported
for (const auto& s : a3)
std::cout << s << ' ';
}
50 changes: 50 additions & 0 deletions cxx-squid/src/test/resources/parser/own/C++11/const-expr.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#include <iostream>
#include <stdexcept>

// The C++11 constexpr functions use recursion rather than iteration
// (C++14 constexpr functions may use local variables and loops)
constexpr int factorial(int n)
{
return n <= 1 ? 1 : (n * factorial(n - 1));
}

// literal class
class conststr {
const char * p;
std::size_t sz;
public:
template<std::size_t N>
constexpr conststr(const char(&a)[N]) : p(a), sz(N - 1) {}
// constexpr functions signal errors by throwing exceptions
// in C++11, they must do so from the conditional operator ?:
constexpr char operator[](std::size_t n) const {
return n < sz ? p[n] : throw std::out_of_range("");
}
constexpr std::size_t size() const { return sz; }
};

// C++11 constexpr functions had to put everything in a single return statement
// (C++14 doesn't have that requirement)
constexpr std::size_t countlower(conststr s, std::size_t n = 0,
std::size_t c = 0) {
return n == s.size() ? c :
s[n] >= 'a' && s[n] <= 'z' ? countlower(s, n + 1, c + 1) :
countlower(s, n + 1, c);
}

// output function that requires a compile-time constant, for testing
template<int n> struct constN {
constN() { std::cout << n << '\n'; }
};

int main()
{
std::cout << "4! = ";
constN<factorial(4)> out1; // computed at compile time

volatile int k = 8; // disallow optimization using volatile
std::cout << k << "! = " << factorial(k) << '\n'; // computed at run time

std::cout << "Number of lowercase letters in \"Hello, world!\" is ";
constN<countlower("Hello, world!")> out2; // implicitly converted to conststr
}
33 changes: 33 additions & 0 deletions cxx-squid/src/test/resources/parser/own/C++11/decl-type.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#include <iostream>

struct A {
double x;
};
const A* a = new A{ 0 };

decltype(a->x) x3; // type of x3 is double (declared type)
decltype((a->x)) x4 = x3; // type of x4 is const double& (lvalue expression)

//ToDo - make this work
//template <class T, class U>
//auto add(T t, U u) -> decltype(t + u); // return type depends on template parameters

int main()
{
int i = 33;
decltype(i) j = i * 2;

std::cout << "i = " << i << ", "
<< "j = " << j << '\n';

auto f = [](int a, int b) -> int {
return a*b;
};

decltype(f) f2 = f; // the type of a lambda function is unique and unnamed
i = f(2, 2);
j = f2(3, 3);

std::cout << "i = " << i << ", "
<< "j = " << j << '\n';
}
19 changes: 19 additions & 0 deletions cxx-squid/src/test/resources/parser/own/C++11/decl-val.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#include <utility>
#include <iostream>

struct Default {
int foo() const { return 1; }
};

struct NonDefault {
NonDefault(const NonDefault&) {}
int foo() const { return 1; }
};

int main()
{
decltype(Default().foo()) n1 = 1; // int n1
// decltype(NonDefault().foo()) n2 = n1; // will not compile
decltype(std::declval<NonDefault>().foo()) n2 = n1; // int n2
std::cout << "n2 = " << n2 << '\n';
}
53 changes: 53 additions & 0 deletions cxx-squid/src/test/resources/parser/own/C++11/enums-11.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#include <iostream>
// enum that takes 16 bits
enum smallenum : int16_t {
A,
B,
C
};


// color may be red (value 0), yellow (value 1), green (value 20), or blue (value 21)
enum color {
red,
yellow,
green = 20,
blue
};

// altitude may be altitude::high or altitude::low
enum class altitude : char {
high = 'h',
low = 'l', // C++11 allows the extra comma
};

// the constant d is 0, the constant e is 1, the constant f is 3
enum { d, e, f = e + 2 };

//enumeration types (both scoped and unscoped) can have overloaded operators
std::ostream& operator<<(std::ostream& os, color c)
{
switch (c) {
case red: os << "red"; break;
case yellow: os << "yellow"; break;
case green: os << "green"; break;
case blue: os << "blue"; break;
default: os.setstate(std::ios_base::failbit);
}
return os;
}
std::ostream& operator<<(std::ostream& os, altitude al)
{
return os << static_cast<char>(al);
}

int main()
{
color col = red;
altitude a;
a = altitude::low;

std::cout << "col = " << col << '\n'
<< "a = " << a << '\n'
<< "f = " << f << '\n';
}
14 changes: 14 additions & 0 deletions cxx-squid/src/test/resources/parser/own/C++11/final-specifier.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
struct A
{
virtual void foo() final; // A::foo is final
void bar() final; // Error: non-virtual function cannot be final
};

struct B final : A // struct B is final
{
void foo(); // Error: foo cannot be overridden as it's final in A
};

struct C : B // Error: B is final
{
};
26 changes: 26 additions & 0 deletions cxx-squid/src/test/resources/parser/own/C++11/lambda-function.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#include <vector>
#include <iostream>
#include <algorithm>
#include <functional>

int main()
{
std::vector<int> c{ 1,2,3,4,5,6,7 };
int x = 5;
c.erase(std::remove_if(c.begin(), c.end(), [x](int n) { return n < x; }), c.end());

std::cout << "c: ";
for (auto i : c) {
std::cout << i << ' ';
}
std::cout << '\n';

// the type of a closure cannot be named, but can be inferred with auto
auto func1 = [](int i) { return i + 4; };
std::cout << "func1: " << func1(6) << '\n';

// like all callable objects, closures can be captured in std::function
// (this may incur unnecessary overhead)
std::function<int(int)> func2 = [](int i) { return i + 4; };
std::cout << "func2: " << func2(6) << '\n';
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#include <iostream>
#include <vector>
#include <map>
#include <string>

struct Foo {
std::vector<int> mem = { 1,2,3 }; // list-initialization of a non-static member
std::vector<int> mem2;
Foo() : mem2{ -1, -2, -3 } {} // list-initialization of a member in constructor
};

std::pair<std::string, std::string> f(std::pair<std::string, std::string> p)
{
return{ p.second, p.first }; // list-initialization in return statement
}

int main()
{
int n0{}; // value-initialization (to zero)
int n1{ 1 }; // direct-list-initialization
std::string s1{ 'a', 'b', 'c', 'd' }; // initializer-list constructor call
std::string s2{ s1, 2, 2 }; // regular constructor call
std::string s3{ 0x61, 'a' }; // initializer-list ctor is preferred to (int, char)

int n2 = { 1 }; // copy-list-initialization
double d = double{ 1.2 }; // list-initialization of a temporary, then copy-init

std::map<int, std::string> m = { // nested list-initialization
{ 1, "a" },
{ 2,{ 'a', 'b', 'c' } },
{ 3, s1 }
};

std::cout << f({ "hello", "world" }).first // list-initialization in function call
<< '\n';

const int(&ar)[2] = { 1,2 }; // binds a lvalue reference to a temporary array
int&& r1 = { 1 }; // binds a rvalue reference to a temporary int
// int& r2 = {2}; // error: cannot bind rvalue to a non-const lvalue ref

// int bad{1.0}; // error: narrowing conversion
unsigned char uc1{ 10 }; // okay
// unsigned char uc2{-1}; // error: narrowing conversion

Foo f;

std::cout << n0 << ' ' << n1 << ' ' << n2 << '\n'
<< s1 << ' ' << s2 << ' ' << s3 << '\n';
for (auto p : m)
std::cout << p.first << ' ' << p.second << '\n';
for (auto n : f.mem)
std::cout << n << ' ';
for (auto n : f.mem2)
std::cout << n << ' ';
}
Loading

0 comments on commit c18ec78

Please sign in to comment.