Skip to content
Snippets Groups Projects
Commit b8e189c7 authored by Sandipan Mohanty's avatar Sandipan Mohanty
Browse files

Add day2 examples

parent 9b678653
No related branches found
No related tags found
No related merge requests found
Showing
with 591 additions and 0 deletions
#include <iostream>
#include <vector>
class collect {
std::vector<int> dat;
public:
auto operator|(int i) -> collect&
{
dat.push_back(i);
return *this;
}
auto operator~() const noexcept -> decltype(dat)
{
return dat;
}
};
auto main() -> int
{
auto C = collect{};
C | 1 | 2 | 3 | 4 ;
for (auto el : (~C)) {
std::cout << el << "\n";
}
}
#include <iostream>
class complex_number
{
public:
// If the constructor is meant to do nothing, let the compiler generate it
constexpr complex_number() noexcept = default;
// Same for the destructor
~complex_number() noexcept = default;
// Constructor with real and imaginary parts
constexpr complex_number(double re, double im) noexcept;
// Constructor with only a real part. It "delegates" its work to the
// constructor above. See its implementation below
constexpr complex_number(double re) noexcept;
// Copy constructor with trivial member wise copy
constexpr complex_number(const complex_number &c) noexcept = default;
// Trivial assignment operator
constexpr auto operator=(const complex_number& c) noexcept -> complex_number& = default;
// Move constructor with trivial member wise move
constexpr complex_number(complex_number &&c) noexcept = default;
// Move assignment operator
constexpr auto operator=(complex_number&& c) noexcept -> complex_number& = default;
// Arithmetic operators changing the calling object
constexpr auto operator+=(const complex_number&) noexcept -> complex_number&;
constexpr auto operator-=(const complex_number&) noexcept -> complex_number&;
constexpr auto operator*=(const complex_number&) noexcept -> complex_number&;
// Accessor functions
constexpr auto real() const noexcept -> double { return m_real; }
constexpr auto imag() const noexcept -> double { return m_imag; }
constexpr auto modulus() const noexcept -> double { return m_real * m_real + m_imag * m_imag; }
// Non-member function which accesses private data
// This is needed to write things like
// double d; complex_number c;
// complex_number e = d*c;
// Because the operator is called with the LHS as the refering object
friend constexpr auto operator*(double x, const complex_number&) noexcept -> complex_number;
// Teach ostream how to output your class
friend auto operator<<(std::ostream& os, const complex_number& c) -> std::ostream&;
private:
// Data variables. Private. Initialised.
double m_real=0,m_imag=0;
};
// Note syntax for initialisation. You can assign to m_real and m_imag in the
// function body, but the initialiser syntax is more compact.
constexpr complex_number::complex_number(double re, double im) noexcept : m_real{re},m_imag{im} {}
// This is a constructor which gets its work done by calling another constructor.
// This is allowed since C++11.
constexpr complex_number::complex_number(double re) noexcept : complex_number{re,0} {}
// Note the compact notation for the return statement. The "type" of the
// return value is, of course, known from the function signature. So,
// the compiler knows that it has to construct a complex_number from
// whatever that comes after the keyword "return". Since we have
// only a set of braces with two arguments, it looks for a constructor
// with two double arguments, and uses that.
// The following functions are not member functions. They don't need to be.
constexpr auto operator+(const complex_number& b, const complex_number& c) noexcept -> complex_number
{
return {b.real()+c.real(),b.imag()+c.imag()};
}
constexpr auto operator-(const complex_number& b, const complex_number& c) noexcept -> complex_number
{
return {b.real()-c.real(),b.imag()-c.imag()};
}
constexpr auto operator*(const complex_number& b, const complex_number& c) noexcept -> complex_number
{
return {b.real()*c.real()-b.imag()*c.imag(), b.real()*c.imag() + b.imag()*c.real()};
}
// Modifying operators do not construct a new object and return it, but
// instead directly change the data in the calling object. Look how
// the function returns the calling object through the "this" pointer!
// This is needed to write nested statements like z=z1*(z2+=z1);
constexpr auto complex_number::operator+=(const complex_number& c) noexcept -> complex_number&
{
m_real+=c.m_real;
m_imag+=c.m_imag;
return *this;
}
constexpr auto complex_number::operator-=(const complex_number& c) noexcept -> complex_number&
{
m_real-=c.m_real;
m_imag-=c.m_imag;
return *this;
}
constexpr auto complex_number::operator*=(const complex_number& c) noexcept -> complex_number&
{
// Temporary store for new real value
double tmprl=m_real*c.m_real-m_imag*c.m_imag;
// Calculate new imaginary value using old real and imaginary parts
m_imag=m_real*c.m_imag+m_imag*c.m_real;
m_real=tmprl;
return *this;
}
constexpr auto operator*(double x, const complex_number& c) noexcept -> complex_number
{
return {x*c.m_real,x*c.m_imag};
}
auto operator<<(std::ostream& os, const complex_number& c) -> std::ostream&
{
os << c.m_real;
if (c.m_imag>0) os << '+';
os << c.m_imag << 'i';
return os;
}
auto main() -> int
{
static_assert(complex_number { 0.1, -2.3 }.modulus() > 0, "");
complex_number z0{0.3,0.84}, z;
for (int i=0; i<10; ++i) {
z = z*z + z0;
std::cout << z << "\n";
}
}
#include <iostream>
struct v3 { double x, y, z; };
struct pars { int offset; v3 velocity; };
std::ostream & operator<<(std::ostream & os, const v3 & v) { return os << v.x << ", " << v.y << ", " << v.z << " "; }
auto example_func(pars p)
{
std::cout << p.offset << " with velocity " << p.velocity << "\n";
}
int main()
{
example_func({.offset = 5, .velocity = {.x=1., .y = 2., .z=3.}});
}
#include <iostream>
#include <stdexcept>
double f(double x)
{
double answer=1;
if (x>=0 and x<10) {
while (x>0) {
answer*=x;
x-=1;
}
} else {
throw(std::invalid_argument("Bad parameter value " + std::to_string(x)));
}
return answer;
}
int main()
{
double x=9.0;
try {
std::cout<<"Enter start point : ";
std::cin >> x;
auto res=f(x);
std::cout <<"The result is "<<res<<'\n';
} catch (std::exception &ex) {
std::cerr<<"Cought exception "<<ex.what()<<'\n';
}
}
#include <iostream>
unsigned long euclid_gcd(unsigned long smaller, unsigned long larger)
{
if (smaller > larger)
std::swap(smaller, larger);
while (smaller != 0) {
auto rem = larger % smaller;
larger = smaller;
smaller = rem;
}
return larger;
}
int main(int argc, char* argv[])
{
if (argc != 3) {
std::cout << "Usage:\n"
<< argv[0] << " number1 number2\n";
return 1;
}
unsigned long n1 = std::stoul(argv[1]), n2 = std::stoul(argv[2]);
std::cout << euclid_gcd(n1, n2) << "\n";
}
#include <iostream>
class Temperature
{
double v = 0.0;
public:
enum class Unit { K, C };
constexpr auto ConvFrom(double x, Unit u) {
switch (u) {
case Unit::K : return x;
case Unit::C :
default: return 273.15 + x;
};
}
Temperature() = default;
Temperature(double x, Unit u) : v{ ConvFrom(x, u) } {}
auto Kelvin() const noexcept -> double { return v; }
auto Celsius() const noexcept -> double { return v; }
};
auto operator "" _K(long double d) -> Temperature
{
return { static_cast<double>(d), Temperature::Unit::K };
}
auto operator "" _C(long double d) -> Temperature
{
return { static_cast<double>(d), Temperature::Unit::C };
}
auto main() -> int
{
auto T1 = 273.15_K;
auto T2 = 100.0_C;
std::cout << T1.Celsius() << "\t" << T2.Celsius() << "\n";
}
#include "Vbose.hh"
void testfunc(int i)
{
std::cout << "Entering testfunc with argument " << i << "\n";
Vbose v{"VFROMTESTFUNC"};
if (i > 2) {
std::cout << "Exiting testfunc() via exception.\n";
throw 2;
}
else std::cout << "Passed check point 2\n";
std::cout << "Last line of testfunc("<< i << ")\n";
}
auto main() -> int
{
try {
testfunc(0);
testfunc(1);
testfunc(3);
testfunc(2);
} catch (int err) {
std::cout << "Caught exception " << err << "\n";
}
}
#include <iostream>
class A {};
class B {};
auto operator+(A x, A y) -> A
{
std::cout << "Called operator+() with two A type arguments\n";
return x;
}
auto operator+(B x, B y) -> B
{
std::cout << "Called operator+() with two B type arguments\n";
return x;
}
auto operator@(A x, B y) -> A
{
std::cout << "Called operator+() with one A type and one B type argument\n";
return x;
}
auto main() -> int
{
A a1, a2;
B b1, b2;
a1 + a2;
a1 @ b1;
b1 + b2;
// b1 + a2;
}
#include <cmath>
#include <expected>
#include <iostream>
auto mysqrt(double x) -> std::expected<double, std::string>
{
const auto eps = 1.0e-12;
const auto eps2 = eps * eps;
if (x >= 0.) {
auto r0 = 0.5 * (1. + x);
auto r1 = x / r0;
while ((r0 - r1) * (r0 - r1) > eps2) {
r0 = 0.5 * (r0 + r1);
r1 = x / r0;
}
return { r1 };
} else {
return std::unexpected { "Unexpected input!" };
}
}
auto main() -> int
{
double x {};
std::cout << "Enter a positive real number: ";
std::cin >> x;
if (auto rm = mysqrt(x); rm) {
auto rs = std::sqrt(x);
std::cout << "Square root with own function = " << rm.value() << "\n";
std::cout << "Square root with standard function = " << rs << "\n";
std::cout << "Difference = " << rm.value() - rs << "\n";
} else {
std::cout << "Square root did not return an expected value. Error: " << rm.error() << "\n";
}
}
#include <iostream>
#include <cmath>
using error_code = int;
auto mysqrt(double x) -> double
{
const auto eps = 1.0e-12;
const auto eps2 = eps * eps;
if (x < 0) throw error_code{-1};
auto r0 = 0.5 * (1. + x);
auto r1 = x / r0;
while ((r0 - r1) * (r0 - r1) > eps2) {
r0 = 0.5 * (r0 + r1);
r1 = x / r0;
}
return r1;
}
auto main() -> int
{
double x{};
std::cout << "Enter a positive real number: ";
std::cin >> x;
try {
auto rm = mysqrt(x);
auto rs = std::sqrt(x);
std::cout << "Square root with own function = " << rm << "\n";
std::cout << "Square root with standard function = " << rs << "\n";
std::cout << "Difference = " << rm - rs << "\n";
} catch (error_code& error) {
std::cout << "The input number needs to be positive.\n";
std::cout << "Caught error_code with value " << error << "\n";
}
}
#include <iostream>
#include <cmath>
using error_code = std::string;
auto mysqrt(double x) -> double
{
const auto eps = 1.0e-12;
const auto eps2 = eps * eps;
if (x < 0)
throw error_code{"Asking for square root of a negative number, are you alright?" };
auto r0 = 0.5 * (1. + x);
auto r1 = x / r0;
while ((r0 - r1) * (r0 - r1) > eps2) {
r0 = 0.5 * (r0 + r1);
r1 = x / r0;
}
return r1;
}
auto main() -> int
{
double x{};
std::cout << "Enter a positive real number: ";
std::cin >> x;
try {
auto rm = mysqrt(x);
auto rs = std::sqrt(x);
std::cout << "Square root with own function = " << rm << "\n";
std::cout << "Square root with standard function = " << rs << "\n";
std::cout << "Difference = " << rm - rs << "\n";
} catch (error_code& error) {
std::cout << "Caught error_code with value:\"" << error << "\"\n";
}
}
#include <stdexcept>
#include <iostream>
#include <cmath>
auto mysqrt(double x) -> double
{
const auto eps = 1.0e-12;
const auto eps2 = eps * eps;
if (x < 0)
throw std::runtime_error{"Asking for square root of a negative number, are you alright?" };
auto r0 = 0.5 * (1. + x);
auto r1 = x / r0;
while ((r0 - r1) * (r0 - r1) > eps2) {
r0 = 0.5 * (r0 + r1);
r1 = x / r0;
}
return r1;
}
auto main() -> int
{
double x{};
std::cout << "Enter a positive real number: ";
std::cin >> x;
try {
auto rm = mysqrt(x);
auto rs = std::sqrt(x);
std::cout << "Square root with own function = " << rm << "\n";
std::cout << "Square root with standard function = " << rs << "\n";
std::cout << "Difference = " << rm - rs << "\n";
} catch (std::runtime_error& error) {
std::cout << "Caught runtime_error:\"" << error.what() << "\"\n";
}
}
#include <stdexcept>
#include <iostream>
#include <cmath>
auto mysqrt(double x) -> double
{
const auto eps = 1.0e-12;
const auto eps2 = eps * eps;
if (x < 0)
throw std::runtime_error{"Asking for square root of a negative number, are you alright?" };
auto r0 = 0.5 * (1. + x);
auto r1 = x / r0;
while ((r0 - r1) * (r0 - r1) > eps2) {
r0 = 0.5 * (r0 + r1);
r1 = x / r0;
}
return r1;
}
auto main() -> int
{
double x{};
std::cout << "Enter a positive real number: ";
std::cin >> x;
try {
auto rm = mysqrt(x);
auto rs = std::sqrt(x);
std::cout << "Square root with own function = " << rm << "\n";
std::cout << "Square root with standard function = " << rs << "\n";
std::cout << "Difference = " << rm - rs << "\n";
} catch (std::runtime_error& error) {
std::cout << "Caught runtime_error:\"" << error.what() << "\"\n";
}
}
#include <iostream>
#include <cmath>
#include <optional>
auto mysqrt(double x) -> std::optional<double>
{
std::optional<double> ans;
const auto eps = 1.0e-12;
const auto eps2 = eps * eps;
if (x >= 0.) {
auto r0 = 0.5 * (1. + x);
auto r1 = x / r0;
while ((r0 - r1) * (r0 - r1) > eps2) {
r0 = 0.5 * (r0 + r1);
r1 = x / r0;
}
ans = r1;
}
return ans;
}
auto main() -> int
{
double x{};
std::cout << "Enter a positive real number: ";
std::cin >> x;
if (auto rm = mysqrt(x); rm) {
auto rs = std::sqrt(x);
std::cout << "Square root with own function = " << rm.value() << "\n";
std::cout << "Square root with standard function = " << rs << "\n";
std::cout << "Difference = " << rm.value() - rs << "\n";
} else {
std::cout << "Square root does not contain a value. Bad input!\n";
}
}
#include <iostream>
class A{};
class B{};
void f(int i, A a)
{
std::cout << "Called version with input types (int, A)\n";
}
void f(int i, B b)
{
std::cout << "Called version with input types (int, B)\n";
}
auto main() -> int
{
A xa;
B xb;
f(0, xa);
f(0, xb);
}
#include <iomanip>
#include <iostream>
#include <string>
#include "Vbose.hh"
auto operator<<(std::ostream& os, const Vbose* obj) -> std::ostream&
{
os << std::hex << (size_t)(obj);
return os;
}
auto f(std::string a) -> Vbose
{
std::cout << "Entering f()\n";
Vbose tmp(a);
if (tmp.getval() == "") {
std::cerr << "Warning! Empty string used to construct object!\n";
}
std::cout << "Leaving f()\n";
return tmp;
}
void g(Vbose v)
{
std::cout << "Called g with " << &v << "(" << v.getval() << ")\n";
v.setval(v.getval() + "_modified");
std::cout << "g() : Modified v to " << v.getval() << "\n";
}
auto main() -> int
{
std::cout << "Entering main()\n";
std::cout << "Constructing a and b\n";
Vbose a, b("Mercury");
{
Vbose c("UnusedVar");
}
std::cout << "Calling f and assigning result to a\n";
a = f("Venus");
std::cout << "Calling f without assigning the result\n";
f("Jupitor");
std::cout << "Statement after calling f without assigning result\n";
std::cout << "Calling g with b\n";
g(b);
std::cout << "Statement after calling g with b\n";
std::cout << "Value of b, after call to g, is " << b.getval() << "\n";
std::cout << "Calling g with a+b\n";
g(a + b);
std::cout << "Calling g with std::move(a)\n";
g(std::move(a));
std::cout << "Leaving main()\n";
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment