Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <vector>
- #include <iterator>
- #include <stdlib.h>
- #include <type_traits>
- #include <stdexcept>
- #include <cmath>
- using namespace std;
- template <typename T, T B = std::numeric_limits<T>::min(), T E = std::numeric_limits<T>::max()>
- class Range
- {
- T value;
- template <typename T3, T3 B3, T3 E3>
- friend class Range;
- public:
- typedef T Type;
- Range(T value) : value(value)
- {
- if (value < B || value > E)
- throw std::out_of_range("Value is out of range");
- }
- template<typename T2, T2 BO, T2 EO>
- Range(const Range<T2, BO, EO> &o)
- {
- if (o.value < B || o.value > E)
- throw std::out_of_range("Value is out of range");
- value = o.value;
- }
- template<typename T2, T2 BO, T2 EO>
- Range& operator=(const Range<T2, BO, EO> &o)
- {
- if (o.value < B || o.value > E)
- throw std::out_of_range("Value is out of range");
- value = o.value;
- }
- template<typename To, To Bo, To Eo>
- Range<T, B + Bo, E + Eo> operator+(const Range<To, Bo, Eo> &o)
- {
- return { value + o.value };
- }
- explicit operator T() const { return value; }
- static constexpr T min() { return B; }
- static constexpr T max() { return E; }
- static constexpr T length() { return E - B; }
- T distanceFromMin() { return value - min(); }
- };
- template<typename T, T B, T E>
- std::ostream& operator<<(std::ostream &os, const Range<T, B, E> &range)
- {
- cout << T(range) << " in [" << range.min() << " .. " << range.max() << "]";
- }
- template<int a, int b>
- using IntRange = Range<int, a, b>;
- template <typename Index, typename Value>
- class Array
- {
- Value m_data[Index::length()];
- public:
- static constexpr typename Index::Type size() { return Index::length(); }
- Value& operator[](Index idx)
- {
- return m_data[idx.distanceFromMin()];
- }
- Value operator[](Index idx) const
- {
- return m_data[idx.distanceFromMin()];
- }
- Value *begin()
- {
- return std::begin(m_data);
- }
- Value *end()
- {
- return std::end(m_data);
- }
- };
- template<typename T, T a, T b>
- Range<T, T(std::sqrt(std::min<T>(0, a))), T(std::sqrt(b))> sqrt(const Range<T, a, b>& r)
- {
- return std::sqrt(T(r));
- }
- void tryprint(auto f)
- {
- try
- {
- cout << f() << endl;
- }
- catch (const std::exception &e)
- {
- cout << e.what() << endl;
- }
- }
- auto f(auto a, auto b, auto c)
- {
- return sqrt(sqrt(a + b) + c);
- }
- int main()
- {
- IntRange<-25, 33> a = -5;
- IntRange<25, 144> b = 55;
- Range c = a + b;
- cout << "a = " << a << endl;
- cout << "b = " << b << endl;
- cout << "c = " << c << endl;
- cout << "sqrt(b) = " << sqrt(b) << endl;
- cout << "f(a,b,c) = " << f(a, b, c) << endl;
- Range e = -5234;
- cout << "e = " << e << endl;
- Array<IntRange<5, 13>, int> arr;
- cout << "Arr size: " << arr.size() << endl;
- for (int i = 5; i <= 13; i++) arr[i] = i * 2;
- cout << "Arr elems: ";
- for (int i : arr)
- cout << i << " ";
- cout << endl;
- cout << "arr[7] = "; tryprint([&]() { return arr[7]; });
- cout << "arr[1] = "; tryprint([&]() { return arr[1]; });
- cout << "d = "; tryprint([&]() {
- IntRange<0, 10> d = c;
- return d;
- });
- char _;
- cin >> _;
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement