c++11 – C++ generic callback implementation

I have a code that takes messages from flash player in a form of XML parse them into function and arguments and calls a registered callback for that function.
The piece of code that I want to replace is something nicely done (almost) generic Callback mechanism:
code for the generic callback implementation of flashSDK (ASInterface.inl).

The problem with it is that this code is written for flash and I want to replace the flash and use other service that will have the same interface. Is there any standard implementation of this callback mechanism (std? boost? something else open sourced?)?

This code implements generic callbacks mechanism that you can register function with number of arguments and types in a map:

void SomethingHappened(int a, int b) {print a + b;}
void SomethingElseHappened(string abcd) {print abcd;}
callbacks("SomethingHappened") = &SomethingHappened;
callbacks("SomethingElseHappened") = &SomethingElseHappened;

and than search for it and call with an array of arguments:

Callbacks::iterator itCallback = callbacks.find(functionName);
if (itCallback != callbacks.end())
{
    HRESULT result = itCallback->second.Call(arguments, returnValue);
}

full usage example:

//init callbacks
typedef std::map<std::wstring, Callback> callbacks;
void SomethingHappened(int a, int b) {print a + b;}
void SomethingElseHappened(string abcd) {print abcd;}
callbacks(functionName) = &SomethingHappened;

void MessageArrived(string xmlInput)
{
    string functionName = parseFunctionName(xmlInput);
    Callbacks::iterator itCallback = callbacks.find(functionName);
    if (itCallback != callbacks.end())
    {
        //parse arguments
        std::vector<std::wstring> args;
        _Args::split(xml, args);
        ASValue::Array arguments;
        for (size_t i = 0, s = args.size(); i < s; ++i)
        {
            ASValue arg; arg.FromXML(args(i));
            arguments.push_back(arg);
        }
        ASValue returnValue;
        //***this is where the magic happens: call the function***
        HRESULT result = itCallback->second.Call(arguments, returnValue);
        return result;
    }
}

c++11 – C++ Creating custom vector

I am new to C++ and Data structures, so I have started writing a custom vector as a practice.
Please provide critique and advice.
I know it is quite long, so thank you very much in advance. I just want to get better and not to get used to bad practices.

     #pragma once
    
    #include <iostream>
    #include <utility>
    #include <algorithm>
    #include <cstddef>
    
    namespace DataStructures {
    
    template<typename T>
    class vector {
    
    public:
        using size_type = std::size_t;
    
        template <typename DataType>
        class BDIterator {
            friend class vector;
    
        public:
            using difference_type = ptrdiff_t;
            using value_type = DataType;
            using pointer = DataType*;
            using reference = DataType&;
            using iterator_category = std::random_access_iterator_tag;
    
            explicit BDIterator(const pointer data = nullptr) : m_address(data) {
            }
    
            reference operator*() const {
                return *m_address;
            }
    
            pointer operator->() const {
                return m_address;
            }
    
            BDIterator& operator++() {
                ++m_address;
                return *this;
            }
    
            BDIterator operator++(int) {
                BDIterator res(*this);
                ++(*this);
                return res;
            }
    
            BDIterator& operator+=(int n) {
                while (n--) {
                    ++(*this);
                }
                return *this;
            }
    
            BDIterator operator+(int n) const {
                BDIterator tmp(*this);
                tmp += n;
                return tmp;
            }
    
            BDIterator& operator--() {
                --m_address;
                return *this;
            }
    
            BDIterator operator--(int) {
                BDIterator res(*this);
                --(*this);
                return res;
            }
    
            BDIterator& operator-=(int n) {
                while (n--) {
                    --(*this);
                }
                return *this;
            }
    
            BDIterator operator-(int n) const {
                BDIterator tmp(*this);
                tmp -= n;
                return tmp;
            }
    
            difference_type operator-(const BDIterator& rhs) const {
                return m_address - rhs.m_address;
            }
    
            reference operator()(size_type ind) const {
                return (*(*this + ind));
            }
    
            bool operator==(const BDIterator& other) const noexcept {
                return m_address == other.m_address;
            }
    
            bool operator!=(const BDIterator& other) const noexcept {
                return !(other == *this);
            }
    
            bool operator<(const BDIterator& other) const noexcept {
                return m_address < other.m_address;
            }
    
            bool operator>(const BDIterator& other) const noexcept {
                return other < *this;
            }
    
        private:
            pointer m_address;
        };
    
        template <>
        class BDIterator<T> {
        public:
            operator BDIterator<const T>() {
                return BDIterator<const T>(m_address);
            }
        };
    
        using iterator = BDIterator<T>;
        using const_iterator = BDIterator<const T>;
    
        template <typename DataType>
        class BDRIterator {
            friend class vector;
    
        public:
            using difference_type = ptrdiff_t;
            using value_type = T;
            using pointer = T*;
            using reference = T&;
            using iterator_category = std::random_access_iterator_tag;
    
            explicit BDRIterator(const pointer data = nullptr) : m_address(data) {}
    
            explicit BDRIterator(BDIterator<T> iterator) : m_address(iterator.m_address - 1) {}
    
            reference operator*() const {
                return *m_address;
            }
    
            pointer operator->() const {
                return m_address;
            }
    
            BDRIterator& operator++() {
                --m_address;
                return *this;
            }
    
            BDRIterator operator++(int) {
                BDRIterator res(*this);
                --(*this);
                return res;
            }
    
            BDRIterator& operator+=(int n) {
                while (n--) {
                    ++(*this);
                }
                return *this;
    
            }
    
            BDRIterator operator+(int n) const {
                BDRIterator tmp(*this);
                tmp -= n;
                return tmp;
            }
    
            BDRIterator& operator--() {
                ++m_address;
                return *this;
            }
    
            BDRIterator operator--(int) {
                BDRIterator res(*this);
                ++(*this);
                return res;
            }
    
            BDRIterator& operator-=(int n) {
                while (n--) {
                    --(*this);
                }
                return *this;
            }
    
            BDRIterator operator-(int n) const {
                BDRIterator tmp(*this);
                tmp += n;
                return tmp;
            }
    
            difference_type operator-(const BDRIterator& rhs) const {
                return m_address - rhs.m_address;
            }
    
            reference operator()(size_type ind) const {
                return (*(m_address - ind));
            }
    
            BDIterator<T> base() {
                return BDIterator<T>(m_address + 1);
            }
    
            bool operator==(const BDRIterator& other) const noexcept {
                return m_address == other.m_address;
            }
    
            bool operator!=(const BDRIterator& other) const noexcept {
                return !(other == *this);
            }
    
            bool operator<(const BDRIterator& other) const noexcept {
                return m_address > other.m_address;
            }
    
            bool operator>(const BDRIterator& other) const noexcept {
                return other < *this;
            }
    
        private:
            pointer m_address;
        };
    
        using reverse_iterator = BDRIterator<T>;
        using const_reverse_iterator = BDRIterator<const T>;
    
        explicit vector(size_type = INITIAL_CAPACITY);
        vector(size_type, const T&);
        template<typename InputIterator, typename = typename std::enable_if<!std::is_integral<InputIterator>::value>::type>
        vector(InputIterator first, InputIterator last) : vector(std::distance(first, last)) {
            while (first != last) {
                emplace_back(*first);
                ++first;
            }
        }
    
        vector(const vector&);
        vector(vector&&) noexcept;
        vector(std::initializer_list<T>);
    
        vector& operator=(vector);
        vector& operator=(vector&&) noexcept;
        vector& operator=(std::initializer_list<T>);
    
        ~vector();
    
        template<typename InputIterator, typename = typename std::enable_if<!std::is_integral<InputIterator>::value>::type>
        void assign(InputIterator, InputIterator) {
            vector tmp(first, last);
            tmp.swap(*this);
        }
        void assign(size_type, const T&);
        void assign(std::initializer_list<T>);
    
        void push_back(const T&);
        void push_back(T&&);
        
        template<typename... Ts>
        void emplace_back(Ts&&...);
    
        void pop_back() noexcept;
    
        iterator erase(const_iterator);
        iterator erase(const_iterator, const_iterator);
    
        iterator insert(iterator position, const T& val);
        iterator insert(iterator position, size_type n, const T& val);
        template<class InputIterator>
        iterator insert(iterator position, InputIterator first, InputIterator last);
        iterator insert(iterator position, T&& val);
        iterator insert(iterator position, std::initializer_list<T> il);
    
        template <typename... Ts>
        iterator emplace(const_iterator position, Ts&&... args);
    
        void reserve(size_type);
        void resize(size_type);
        void resize(size_type, const T&);
    
        T& operator()(size_type);
        const T& operator()(size_type) const;
    
        T& at(size_type);
        const T& at(size_type) const;
    
        T& front();
        const T& front() const;
    
        T& back();
        const T& back() const;
    
        T* data() noexcept;
        const T* data() const noexcept;
    
        bool empty() const noexcept;
        size_type size() const noexcept;
        size_type capacity() const noexcept;
    
        bool contains(const T&) const noexcept;
    
        void shrink_to_fit();
    
        void swap(vector&);
    
        void clear() noexcept;
    
        iterator begin() noexcept {
            return iterator(m_data);
        }
    
        iterator end() noexcept {
            return iterator(m_data + m_size);
        }
    
        const_iterator begin() const noexcept {
            return const_iterator(m_data);
        }
    
        const_iterator end() const noexcept {
            return const_iterator(m_data + m_size);
        }
    
        reverse_iterator rbegin() noexcept {
            return reverse_iterator(end());
        }
    
        reverse_iterator rend() noexcept {
            return reverse_iterator(begin());
        }
    
        const_reverse_iterator rbegin() const noexcept {
            return const_reverse_iterator(end());
        }
    
        const_reverse_iterator rend() const noexcept {
            return const_reverse_iterator(begin());
        }
    
        const_iterator cbegin() const noexcept {
            return begin();
        }
    
        const_iterator cend() const noexcept {
            return end();
        }
    
        const_reverse_iterator crbegin() const noexcept {
            return rbegin();
        }
    
        const_reverse_iterator crend() const noexcept {
            return rend();
        }
    
    private:
        void allocateMemory_(T*&, size_type);
        void destructObjects_() noexcept;
        void moveBackwards_(const_iterator, size_type);
    
    private:
        size_type m_size = 0;
        size_type m_capacity = 0;
        T* m_data = nullptr;
    
        static const short INITIAL_CAPACITY = 2;
        static const short FACTOR = 2;
    };
    
    template<typename T>
    bool operator==(const vector<T>& lhs, const vector<T>& rhs);
    
    template<typename T>
    bool operator!=(const vector<T>& lhs, const vector<T>& rhs);
    
    template<typename T>
    bool operator>(const vector<T>& lhs, const vector<T>& rhs);
    
    template<typename T>
    bool operator>=(const vector<T>& lhs, const vector<T>& rhs);
    
    template<typename T>
    bool operator<(const vector<T>& lhs, const vector<T>& rhs);
    
    template<typename T>
    bool operator<=(const vector<T>& lhs, const vector<T>& rhs);
    
    template<typename T>
    vector<T>::vector(size_type capacity) : m_capacity(capacity) {
        allocateMemory_(m_data, m_capacity);
    }
    
    template<typename T>
    vector<T>::vector(size_type n, const T& val) : vector(n) {
        while (n--) {
            emplace_back(val);
        }
    }
    
    template<typename T>
    vector<T>::vector(const vector& rhs) : vector(rhs.cbegin(), rhs.cend()) {}
    
    template<typename T>
    vector<T>::vector(vector&& rhs) noexcept : m_data(nullptr), m_size(0), m_capacity(0) {
        rhs.swap(*this);
    }
    
    template<typename T>
    vector<T>::vector(std::initializer_list<T> rhs) : vector(rhs.begin(), rhs.end()) {
    }
    
    template<typename T>
    vector<T>& vector<T>::operator=(vector rhs) {
        rhs.swap(*this);
    
        return *this;
        // return *this = vector<T>{rhs}; <- copy-assign via move-assign
    }
    
    template<typename T>
    vector<T>& vector<T>::operator=(vector&& rhs) noexcept {
        rhs.swap(*this);
        return *this;
    }
    
    template<typename T>
    vector<T>& vector<T>::operator=(std::initializer_list<T> il) {
        vector tmp(il.begin(), il.end());
        tmp.swap(*this);
    
        return *this;
    }
    
    template<typename T>
    vector<T>::~vector() {
        clear();
    }
    
    template<typename T>
    void vector<T>::assign(size_type n, const T& val) {
        vector tmp(n, val);
        tmp.swap(*this);
    }
    
    template<typename T>
    void vector<T>::assign(std::initializer_list<T> il) {
        assign(il.begin(), il.end());
    }
    
    template<typename T>
    void vector<T>::push_back(const T& element) {
        emplace_back(element);
    }
    
    template<typename T>
    void vector<T>::push_back(T&& element) {
        emplace_back(std::move(element));
    }
    
    template <typename T>
    template <typename ...Ts>
    void vector<T>::emplace_back(Ts&&... args) {
        if (!m_data || m_size == m_capacity) {
            reserve(m_capacity * FACTOR);
        }
    
        new(m_data + m_size) T(std::forward<Ts>(args)...);
        ++m_size;
    }
    
    template<typename T>
    void vector<T>::pop_back() noexcept {
        m_data(--m_size).~T();
    }
    
    template<typename T>
    typename vector<T>::iterator vector<T>::erase(typename vector<T>::const_iterator position) {
        //std::advance(it,std::distance(cbegin(),position));
        //iterator iter = begin() + ( position - cbegin() );
        //std::move( iter + 1, end(), iter );
        //pop_back();
        //return iter;
        return erase(position, position + 1);
    }
    
    template<typename T>
    typename vector<T>::iterator
        vector<T>::erase(typename vector<T>::const_iterator first, typename vector<T>::const_iterator last) {
        //UB on invalid range
        iterator iter = begin() + (first - cbegin());
        int      removed_elements = last - first;
    
        std::move(last, cend(), iter);
        while (removed_elements--) {
            pop_back();
        }
        return iter;
    }
    
    template<typename T>
    typename vector<T>::iterator vector<T>::insert(vector::iterator position, const T& val) {
        moveBackwards_(position-1, 1);
    
        size_type offset = position - cbegin();
        m_data(offset) = val;
        ++m_size;
        return (begin() + offset);
    }
    
    template<typename T>
    typename vector<T>::iterator vector<T>::insert(vector::iterator position, size_type n, const T& val) {
        moveBackwards_(position-1, n);
    
        size_type offset = position - cbegin();
        for (int i = 0; i < n; ++i) {
            m_data(offset + i) = val;
        }
        m_size += n;
        return (begin() + offset);
    
    }
    
    template<typename T>
    template<class InputIterator>
    typename vector<T>::iterator
        vector<T>::insert(vector::iterator position, InputIterator first, InputIterator last) {
        size_type count = std::distance(first, last);
        moveBackwards_(position-1, count);
        
        size_type offset = position - cbegin();
        int i = 0;
        while (first != last) {
            m_data(offset + i) = *first;
            ++first;
            ++i;
        }
        m_size += count;
        return (begin() + offset);
    }
    
    template<typename T>
    template<typename ...Ts>
    typename vector<T>::iterator vector<T>::emplace(vector<T>::const_iterator position, Ts&&...args)
    {
        moveBackwards_(position, 1);
        size_type offset = position - cbegin();
        new(m_data + offset - 1)T(std::forward<Ts>(args)...);
        ++m_size;
        return (begin() + offset);
    }
    
    template<typename T>
    typename vector<T>::iterator vector<T>::insert(vector::iterator position, T&& val) {
        return emplace(position, std::forward<T>(val));
    }
    
    template<typename T>
    typename vector<T>::iterator vector<T>::insert(vector::iterator position, std::initializer_list<T> il) {
        return insert(position, il.begin(), il.end());
    }
    
    template<typename T>
    void vector<T>::reserve(size_type size) {
        if (size == 0) {
            size = INITIAL_CAPACITY;
        }
        else if (size <= m_capacity) {
            return;
        }
    
        T* newData = nullptr;
        allocateMemory_(newData, size);
    
        size_type i = 0;
        for (; i < m_size; ++i) {
            new(newData + i)T(std::move(m_data(i)));
        }
    
        clear();
    
        m_data = newData;
        m_capacity = size;
        m_size = i;
    }
    
    template<typename T>
    void vector<T>::resize(size_type size) {
        resize(size, T());
    }
    
    template<typename T>
    void vector<T>::resize(size_type size, const T& value) {
        reserve(size);
        if (size <= m_size) {
            while (m_size > size) {
                pop_back();
            }
        }
        else {
            while (m_size < size) {
                push_back(value);
            }
        }
    }
    
    template<typename T>
    T& vector<T>::operator()(size_type idx) {
        return *(m_data + idx);
    }
    
    template<typename T>
    const T& vector<T>::operator()(size_type idx) const {
        return *(m_data + idx);
    }
    
    template<typename T>
    T& vector<T>::at(size_type idx) {
        if (idx >= m_size) {
            throw (std::out_of_range("Invalid index"));
        }
        return *(m_data + idx);
    }
    
    template<typename T>
    const T& vector<T>::at(size_type idx) const {
        if (idx >= m_size) {
            throw (std::out_of_range("Invalid index"));
        }
        return *(m_data + idx);
    }
    
    template<typename T>
    T& vector<T>::front() {
        return *m_data;
    }
    
    template<typename T>
    const T& vector<T>::front() const {
        return *m_data;
    }
    
    template<typename T>
    T& vector<T>::back() {
        return *(m_data + m_size - 1);
    }
    
    template<typename T>
    const T& vector<T>::back() const {
        return *(m_data + m_size - 1);
    
    }
    
    template<typename T>
    T* vector<T>::data() noexcept {
        return m_data;
    }
    
    template<typename T>
    const T* vector<T>::data() const noexcept {
        return m_data;
    }
    
    template<typename T>
    bool vector<T>::empty() const noexcept {
        return (m_size == 0);
    }
    
    template<typename T>
    typename vector<T>::size_type vector<T>::size() const noexcept {
        return m_size;
    }
    
    template<typename T>
    typename vector<T>::size_type vector<T>::capacity() const noexcept {
        return m_capacity;
    }
    
    template<typename T>
    bool vector<T>::contains(const T& element) const noexcept {
        for (int i = 0; i < m_size; ++i) {
            if (m_data(i) == element) {
                return true;
            }
        }
        return false;
    }
    
    template<typename T>
    void vector<T>::shrink_to_fit() {
        vector(*this).swap(*this);
    }
    
    template<typename T>
    void vector<T>::swap(vector& rhs) {
        using std::swap;
        swap(m_data, rhs.m_data);
        swap(m_size, rhs.m_size);
        swap(m_capacity, rhs.m_capacity);
    }
    
    template<typename T>
    void vector<T>::clear() noexcept {
        destructObjects_();
    
        operator delete(m_data);
        m_data = nullptr;
        m_capacity = 0;
    }
    
    template<typename T>
    void vector<T>::allocateMemory_(T*& destination, size_type capacity) {
        destination = static_cast<T*>(operator new()(capacity * sizeof(T)));
    }
    
    template<typename T>
    void vector<T>::destructObjects_() noexcept {
        while (!empty()) {
            pop_back();
        }
    }
    
    template<typename T>
    void vector<T>::moveBackwards_(vector::const_iterator position, size_type space) {
        size_type elementsToMove = end() - position;
        if (m_size + space >= m_capacity) {
            reserve(m_capacity * FACTOR);
        }
        for (int i = 0; i < elementsToMove; ++i) {
            new(m_data + m_size + space - i) T(std::move(m_data(m_size - i)));
        }
    }
    
    template<typename T>
    bool operator==(const vector<T>& lhs, const vector<T>& rhs) {
        if (lhs.size() != rhs.size()) {
            return false;
        }
        for (int i = 0; i < lhs.size(); ++i) {
            if (lhs(i) != rhs(i)) {
                return false;
            }
        }
        return true;
    
    }
    
    template<typename T>
    bool operator!=(const vector<T>& lhs, const vector<T>& rhs) {
        return !(lhs == rhs);
    }
    
    template<typename T>
    bool operator>(const vector<T>& lhs, const vector<T>& rhs) {
        return rhs < lhs;
    }
    
    template<typename T>
    bool operator>=(const vector<T>& lhs, const vector<T>& rhs) {
        return !(lhs < rhs);
    }
    
    template<typename T>
    bool operator<(const vector<T>& lhs, const vector<T>& rhs) {
        int i = 0;
        while (i < lhs.size() && i < rhs.size() && lhs(i) == rhs(i)) {
            ++i;
        }
        if (i == lhs.size() || i == rhs.size()) {
            return lhs.size() < rhs.size();
        }
        return lhs(i) < rhs(i);
    }
    
    template<typename T>
    bool operator<=(const vector<T>& lhs, const vector<T>& rhs) {
        return !(rhs < lhs);
    }
    
    }

Questions:

  • I can’t understand this part:
    template<typename InputIterator, typename = typename std::enable_if<!std::is_integral<InputIterator>::value>::type>
  1. Why do I need typename = ?
  2. Is there any way I can separate declaration from definition here?

c++ – Using c++11 random header to generate random numbers

I’m a newbie to programming and the usage of c++11 random header to generate random numbers caught my eye.
I have been trying to learn it for some time, but I was unsuccessful.
Recently, I tried this way and it worked. Any adivce on how to improve it or a better source to learn it from?

#include <iostream>
#include <random>
#include <ctime>
int main()
{
   std::default_random_engine random_engine(time(0));
   for (int i = 1; i <= 100; i++)
   {
    std::uniform_int_distribution<int> num(1, 100);
    std::cout << i << "==> " << num(random_engine) << std::endl;
   }
    return 0;
}

c++11 – Grade Calculator (New OOP Version from one previous)

I’m trying to develop an OOP way of thinking. I was hoping someone would be kind enough to spare some of their valuable time to review my Grade Calculator OOP program. As always, I’d like to know what I’ve done well, what I should improve upon, and any suggestions on how I could perhaps improve what I have? By the way, I have a class called Class. I probably should prefix it with “cls” so as not to confuse. Treat this program as is supposed to be entered, I haven’t error checked it. The point of this program is to develop in OOP.

   // Task 1.cpp : This file contains the 'main' function. Program execution begins and ends there.


#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
#include <numeric>
#include <string>
class TestPaper
{
public:
    int m_scoreOutOf;  
    bool checkBoundary(int value, int boundary) {
        if (value < 0 || value > boundary) {
            std::cout << "Score must be between " << " 0 and " << boundary << ". Please try again.n";
            return false;
        }
        return true;
    }

};
class Student {
private:
    std::string m_name;
    int m_scoreGot;
public:
   
    Student(std::string name, int scoreGot)
        :m_name(name), m_scoreGot(scoreGot){}

    std::string getName() const { return m_name; }
    int getScoreGot() const { return m_scoreGot; }
};

class Class {
private:
    std::vector<Student>students;
public:
    void AddStudent(TestPaper& testPaper) {
        std::string name = "";
        int scoreGot = 0;
        std::cout << "Enter student name: ";
        std::getline(std::cin >> std::ws, name);
        do
        {
            std::cout << "nWhat did " << name << " score?nEnter a score between 0 and "
                << testPaper.m_scoreOutOf << ": ";
            std::cin >> scoreGot;
        } while (testPaper.checkBoundary(scoreGot, testPaper.m_scoreOutOf) == false);
        students.push_back({ name, scoreGot });
    }

    std::vector<Student>& accessStudents() { return students; }
};

class GradeCalculator {
    TestPaper m_testPaper;
    Class m_ClassOfStudents;
public:
    GradeCalculator(TestPaper testPaper, Class classOfStudents) :m_testPaper(testPaper), m_ClassOfStudents(classOfStudents) {}
    void DisplayMenu() {

        std::cout << "n1. Add student and their graden";
        std::cout << "2. Calculate class scoren";
        std::cout << "3. Modify testpaper (haven't implemented this yet)n";
    }
    

    double averageGrade() {
        auto sum = std::transform_reduce(m_ClassOfStudents.accessStudents().begin(), m_ClassOfStudents.accessStudents().end(), 0.0, std::plus<>(),
            (&)(auto& student) { return calculateGradePercentage(student); });
        return sum / m_ClassOfStudents.accessStudents().size();
    }
    double calculateGradePercentage(Student &student)
    {
        return static_cast<double>(student.getScoreGot()) / static_cast<double>(m_testPaper.m_scoreOutOf) * 100;
    }
    void DisplayResult() {
        for (auto& student : m_ClassOfStudents.accessStudents()) {
            std::cout << "Percentage scores are: n";
            std::cout << student.getName() << ": " << calculateGradePercentage(student) << "%n";
        }
        std::cout << "Average grade perecentage: " << averageGrade() << "%n";
    }
    void runProgram() {

        int menuChoice = 0;
        while (true)
        {
            DisplayMenu();
            std::cout << "nEnter a choice from the menu: ";
            std::cin >> menuChoice;
            switch (menuChoice)
            {
            case 1:
                m_ClassOfStudents.AddStudent(m_testPaper);
                break;
            case 2:
                DisplayResult();
                break;
            default:
                std::cout << "Invalid choice!n";
            }
        }
    }
};

int main()
{
    TestPaper testPaper({ 20 });
    Class classOfStudents;
    GradeCalculator calculator(testPaper, classOfStudents);
    calculator.runProgram();
   
}

c++11 – Noughts & Crosses UML Class Diagram

I was told I need code in order for someone to review my UML Class Diagram for my Noughts and Crosses console application. I would like to know if it’s intuitive, whether you could make a program based on it, and whether any improvements need to be made on it. Many thanks in advance to anyone who cares to do so!
enter image description here

    #include <iostream>
    #include <vector>
    #include <ctime>
    #include <cstdlib>       
    #include <algorithm>
    #include <random>
    #include <chrono>
    #include <array>

class Board {
    std::array<unsigned char, 9> m_board;
    std::vector<int>m_validLocations;
public:
    Board();
    auto& get();
    void shuffleValidLocations();
    bool isMoveValid(int move);
    auto& getValidLocation();
    void reset();
    void display() const;
    void removeFromValidLocation(int move);
    ~Board() = default;
};


class Player {
public:
    
    unsigned char m_symbol;
    const std::string m_type;
    int m_wins;
    int m_draws;
    virtual int nextMove(Board& board)  = 0;
    Player(const unsigned char symbol, std::string&& type);
    virtual ~Player() = default;
};

class Human : public Player {
public:
    Human(unsigned char symbol) :Player{ symbol, "Human" } {}
    virtual int nextMove(Board& board)  override;
    virtual ~Human() = default;
};
class Robot : public Player {
public:
    Robot(unsigned char symbol) :Player{ symbol, "Robot" } {}
    virtual int nextMove(Board& board)  override;
    virtual ~Robot() = default;
};
class NoughtsAndCrosses
{
    Player* m_one;
    Player* m_two;
    Player* m_turn;
    Player* m_winner;
    Board m_board;

    bool draw();
    void playerMove();
    void switchPlayers();
    bool win();
public:

    NoughtsAndCrosses(Player& one, Player& two);
    Player* playerWithMostWins();
    Player* play();
    ~NoughtsAndCrosses() = default;
};

auto& Board::get() { return m_board; }
Board::Board()
{
    m_board = { '-', '-', '-', '-', '-', '-', '-', '-', '-', };
    m_validLocations = { 1,2,3,4,5,6,7,8,9 };
}
void Board::shuffleValidLocations() {
    auto seed = std::chrono::system_clock::now().time_since_epoch().count();
    std::default_random_engine e(seed);
    std::shuffle(m_validLocations.begin(), m_validLocations.end(), e);
}
bool Board::isMoveValid(int move) {
    return (std::any_of(m_validLocations.begin(), m_validLocations.end(), (&)(int& num) {return num == move; }));
}
auto& Board::getValidLocation() { return m_validLocations; }
void Board::reset()
{
    std::fill(m_board.begin(), m_board.end(), '-');
    m_validLocations = { 1,2,3,4,5,6,7,8,9 };
}
void Board::display() const
{
    int num = 0;
    for (auto const& cell : m_board)
    {
        num++;
        if (num % 3 == 1) {
            std::cout << "nn";
        }
        if (cell != '-') {
            std::cout << cell << "        ";
        }
        else
        {
            std::cout << num << "        ";
        }
    }
    std::cout << "nn";
}
void Board::removeFromValidLocation(int move) {
    std::remove_if(m_board.begin(), m_board.end(), (&)(auto& number) {
        return number == move;
        });
}

Player::Player(const unsigned char symbol, std::string&& type)
    :m_symbol{ symbol }, m_type{ type }, m_wins{ 0 }, m_draws{ 0 } {}
 int Human::nextMove(Board& board) {
    int move = 0;
    bool isMoveValid = false;
    do
    {
        std::cout << "Enter a number on the board (e.g. 1): ";
        std::cin >> move;
        if (!(isMoveValid = board.isMoveValid(move)))
        {
            std::cout << "Invalid move! Choose a valid location!n";
        }
    } while (!isMoveValid);
    board.removeFromValidLocation(move);
    return move - 1;
}

 int Robot::nextMove(Board& board)   {
    int move = 0;
    board.shuffleValidLocations();
    move = board.getValidLocation().at(0);
    board.getValidLocation().erase(board.getValidLocation().begin());
    return move - 1;
}

NoughtsAndCrosses::NoughtsAndCrosses(Player& one, Player& two)
    :m_one(&one), m_two(&two), m_turn(&one), m_winner(nullptr) {}
bool NoughtsAndCrosses:: draw() {
    return std::all_of(m_board.get().begin(), m_board.get().end(), (&)(auto& pair) {return pair != '-'; });
}
void NoughtsAndCrosses::playerMove()
{
    m_board.get().at(m_turn->nextMove(m_board)) = m_turn->m_symbol;
}
void NoughtsAndCrosses::switchPlayers()
{
    m_turn = m_turn == m_one ? m_two : m_one;
}
bool NoughtsAndCrosses::win() {
    if (m_board.get().at(0) == m_turn->m_symbol && m_board.get().at(1) == m_turn->m_symbol && m_board.get().at(2) == m_turn->m_symbol) {
        m_winner = m_turn;
        return true;
    }
    else if (m_board.get().at(3) == m_turn->m_symbol && m_board.get().at(4) == m_turn->m_symbol && m_board.get().at(5) == m_turn->m_symbol) {
        m_winner = m_turn;
        return true;
    }
    else if (m_board.get().at(6) == m_turn->m_symbol && m_board.get().at(7) == m_turn->m_symbol && m_board.get().at(8) == m_turn->m_symbol) {
        m_winner = m_turn;
        return true;
    }
    else if (m_board.get().at(0) == m_turn->m_symbol && m_board.get().at(3) == m_turn->m_symbol && m_board.get().at(6) == m_turn->m_symbol) {
        m_winner = m_turn;
        return true;
    }
    else if (m_board.get().at(1) == m_turn->m_symbol && m_board.get().at(4) == m_turn->m_symbol && m_board.get().at(7) == m_turn->m_symbol) {
        m_winner = m_turn;
        m_winner->m_wins++;
        return true;
    }
    else if (m_board.get().at(2) == m_turn->m_symbol && m_board.get().at(5) == m_turn->m_symbol && m_board.get().at(8) == m_turn->m_symbol) {
        m_winner = m_turn;
        return true;
    }
    else if (m_board.get().at(0) == m_turn->m_symbol && m_board.get().at(4) == m_turn->m_symbol && m_board.get().at(8) == m_turn->m_symbol) {
        m_winner = m_turn;
        return true;
    }
    else if (m_board.get().at(6) == m_turn->m_symbol && m_board.get().at(4) == m_turn->m_symbol && m_board.get().at(2) == m_turn->m_symbol) {
        m_winner = m_turn;
        return true;
    }
    else
    {
        return false;
    }
}
Player* NoughtsAndCrosses::playerWithMostWins() {
    return m_one->m_wins > m_two->m_wins ? m_one : m_two;
}
Player* NoughtsAndCrosses::play() {
    while (true)
    {
        m_board.display();
        playerMove();
        if (win())
        {
            std::cout << m_winner->m_symbol << " is the winner!n";
            break;
        }
        else if (draw())
        {
            m_winner = nullptr;
            break;
        }
        switchPlayers();
    }
    m_board.display();
    m_board.reset();
    m_turn = m_one;
    return m_winner;
}


int main()
{
    Robot robot1('X');
    Robot robot2('O');

    //pass these in to NoughtsAndCrosses if you want to play human vs human, or one if you want to play human vs Robot
    Human human1('X');
    Human human2('O');
  
    NoughtsAndCrosses game(robot1, robot2);
    int round = 3;
    int roundCount = 0;
    Player* winner = nullptr;
    do
    {
        int gameCount = 1;
        int totalGamesinRound = 3;
        std::cout << "START GAME!n";
        system("pause");
        system("cls");
        std::cout << "nROUND " << ++roundCount << ". . .n";
        do
        {
            std::cout << "Game " << gameCount << " of round " << roundCount << "n";
            winner = game.play();

            if (winner != nullptr)
            {
                std::cout << "Winner of game " << gameCount << " is type: " << winner->m_type << ": " << winner->m_symbol << "n";
                winner->m_wins++;
            }
            else
            {              
                std::cout << "Game " << gameCount << " is a draw!n";  
                robot1.m_draws++;
                robot2.m_draws++;
            }
            gameCount++;
            totalGamesinRound--;
        } while (totalGamesinRound != 0);

        /* std::cout << "Game 2: Human vs Robotn";
         game.play(robot1, robot1);*/
        std::cout << "Wins for " << robot1.m_type << ": Player : " << robot1.m_symbol << " - " << robot1.m_wins << "n";
        std::cout << "Wins for " << robot2.m_type << ": Player : " << robot2.m_symbol << " - " << robot2.m_wins << "n";
        std::cout << "Drawed: " << robot1.m_draws << "n";

        std::cout << "Winner of round " << roundCount << " is " << game.playerWithMostWins()->m_symbol << "n";
        round--;
    } 
    while (round != 0);
}

c++11 – Loan System Calculator

I would really like feedback on this Loan System Calculator. My goal is to get better at OOP design and would like to know if I’ve done a good job in making this scenario OOP? Could I have structured it better? Should I have separated each loan type as a separate class using inheritance? I would like to know what I’ve done well too! Thanks to anyone who spends their time to review it.
enter image description here
// Loan System.cpp : This file contains the ‘main’ function. Program execution begins and ends there.
//

#include <iostream>
#include <vector>
#include <string>
class Customer {
private:
    std::string m_name;
    int m_age;
    double m_salary;
    double m_takeOutLoan;
    std::string m_loanType;
    int m_loanLength;
public:
    Customer():m_name("No name"), m_age(0), m_salary(0), m_takeOutLoan(0), m_loanType("No loan name specified"),m_loanLength(0){}
    
    void SetName(std::string name) { m_name = name; }
    void SetAge(int age) { m_age = age; }
    void SetSalary(double salary) { m_salary = salary; }

    std::string GetName() const { return m_name; }
    int GetAge() const { return m_age; }
    double GetSalary() const { return m_salary; }

    void SetTakeOutLoan(double takeOutLoan) { m_takeOutLoan = takeOutLoan; }
    double GetTakeOutLoan() const { return m_takeOutLoan; }

    std::string GetLoanType() const { return m_loanType; }

    void SetLoanLength(int loanLength) { m_loanLength = loanLength; }
    int GetLoanLength()const { return m_loanLength; }

    void SetLoanType(std::string&& loanType) { m_loanType = loanType; }
};

class Loan {
private:
    std::string m_loanType;
    std::string m_loanLength;
    double m_APR;
    double m_maximumLoan;
public:
    int m_loanPeriod;
    Loan(std::string loanType, std::string loanLength, double APR, double maximumLoan, int loanPeriod)
        :m_loanType(loanType), m_loanLength(loanLength), 
        m_APR(APR), m_maximumLoan(maximumLoan), m_loanPeriod(loanPeriod)  {
    }

    std::string GetLoanType()const { return m_loanType; }
    std::string GetLoanLength()const { return m_loanLength; }
    double GetAPR()const { return m_APR; }
    double GetMaximumLoan() const { return m_maximumLoan; }

    void DisplayLoan() const {

        std::cout << "Loan Type: " << m_loanType << "n";
        std::cout << "Loan Length: " << m_loanLength << "n";
        std::cout << "APR: " << m_APR * 100 << "%n";
        std::cout << "Maximum Loan: " << m_maximumLoan <<  "n";
    }
    int ChoosePaybackPeriod(Customer& customer)  {
        int PaybackPeriod = 0;
        std::cout << "How long do you wish to pay back your loan?: ";
        std::cin >> PaybackPeriod;
        if (PaybackPeriod > 0 && PaybackPeriod <= m_loanPeriod)
        {
            return PaybackPeriod;
        }

        return 0;
    }
};
class LongTerm : public Loan {
private:
public:
    LongTerm():Loan("Standard", "3-5 Years", 0.049, 40000, 5){} 
};

class ShortTerm : public Loan
{
private:
public:
    ShortTerm() :Loan("Standard", "1-2 Years", 0.039, 12000, 2) {}
};
class Emergency : public Loan
{
private:
public:
    Emergency() :Loan("Short", "1-6 Months", 0.299, 3000, 6) {}
};

class LoanSystem 
{
private:
    bool ChooseTakeOutLoan(Customer &customer, double maximumTakeOutLoan)
    {
        double requestAmount = 0;
        std::cout << "How much of " << maximumTakeOutLoan << " do you want to take out?: ";
        std::cin >> requestAmount;
        if (requestAmount > 0 && requestAmount <= maximumTakeOutLoan) {
            customer.SetTakeOutLoan(requestAmount);
            return true;
        }
        else
        {
            return false;
        }
    }

public:
    //Check if they are eligible
    bool isQualified(const Customer &customer) {
        const double boundary = 12000;
        if (customer.GetSalary() < boundary || customer.GetAge() < 18) {
            return false;
        }
        return true;
    }
    
    void OverallCost(Customer &customer, Loan *loan) {

        std::cout << "Loan: " << customer.GetLoanType() << "n";
        std::cout << "Amount: " << customer.GetTakeOutLoan() << "n";
        std::cout << "Time financed: " << customer.GetLoanLength() << " year(s)n";
        std::cout << "APR for one year " << loan->GetAPR() * customer.GetTakeOutLoan() << "n";
        std::cout << "APR for time required " << (loan->GetAPR() * 2) * customer.GetTakeOutLoan() << "n";
        std::cout << "Total payable " << customer.GetTakeOutLoan() + (customer.GetTakeOutLoan() * (loan->GetAPR() * 2)) << "n";
    }
    void calculateLoanType(Customer &customer) 
    {
        double maximumTakeOutLoan = 0;
        int paybackPeriod = 0;
        double APR = 0;
        if (customer.GetAge() > 21 && customer.GetSalary() >= 24000) {
            LongTerm longTerm;
            longTerm.DisplayLoan();

            customer.SetLoanType(longTerm.GetLoanType());
            ChooseTakeOutLoan(customer, longTerm.GetMaximumLoan());
            customer.SetLoanLength(longTerm.ChoosePaybackPeriod(customer));
            OverallCost(customer, &longTerm);
        }
        else if (customer.GetAge() > 18 && customer.GetSalary() >= 21000) {
            ShortTerm shortTerm;          
            shortTerm.DisplayLoan();

            customer.SetLoanType(shortTerm.GetLoanType());       
            ChooseTakeOutLoan(customer, shortTerm.GetMaximumLoan());
            customer.SetLoanLength(shortTerm.ChoosePaybackPeriod(customer));
            OverallCost(customer, &shortTerm);
        }
        else if (customer.GetAge() > 18 && customer.GetSalary() >= 12000) {
            Emergency emergency;        
            emergency.DisplayLoan();

            customer.SetLoanType(emergency.GetLoanType());
            ChooseTakeOutLoan(customer, emergency.GetMaximumLoan());
         
            customer.SetLoanLength(emergency.ChoosePaybackPeriod(customer));
            OverallCost(customer, &emergency);
        }
    }
};

void GetCustomerInformation(Customer &customer) {
    std::string name = "";
    int age = 0;
    double salary = 0;

    std::cout << "Enter your name: ";
    std::getline(std::cin >> std::ws, name);
    customer.SetName(name);

    std::cout << "Enter your age: ";
    std::cin >> age;
    customer.SetAge(age);

    std::cout << "Enter your salary: ";
    std::cin >> salary;
    customer.SetSalary(salary);
}

int main()
{
    LoanSystem loanSystem;
    Customer customer;
   
    GetCustomerInformation(customer);

    std::cout << "Your name is: " << customer.GetName() << "n";
    std::cout << "Your age is: " << customer.GetAge() << "n";
    std::cout << "Your salary is: " << customer.GetSalary() << "n";

    std::cout << "Is " << customer.GetName() << " eligible for a loan?: ";
    
    if (loanSystem.isQualified(customer))
    {
        std::cout << customer.GetName() << " is eligible!n";
    }
    else 
    {
        std::cout << customer.GetName() << " isn't eligible!n";
        return 0;
    }

    loanSystem.calculateLoanType(customer);
    std::cout << "The customer has decided to take out: " << customer.GetTakeOutLoan() << "n";
}

c++11 – Noughts & Crosses (Final Version)

I’ve made a major update to my Noughts & Crosses program, this ISN’T a duplicate! I know it’s not good to use system(“pause”) and system(“cls”), however, I just wanted to make the console screen more readable so resorted to these methods to achieve this. I would like feedback on how well I’ve used std::shared_ptr, the std::algorithm library, and any suggestions on how I can improve. I have also returned a std::shared_ptr null-ptr. A lot of what I’ve done has been intuitive and I’m unsure if what I’ve done is the best way to go about doing certain things. If you run this program, please, just press enter where needed, it’s two robots playing against each other. If you’d like to manually play it, please change the arguments passed into the game.play function to a human.

#include <iostream>
#include <vector>
#include <map>
#include <utility>
#include <algorithm>

#include <random>
#include <ctime>
#include <cstdlib>
#include <ranges>
class Player
{
private:
    std::string m_type;
    unsigned char m_name;
    int m_winTally;
    int m_drawed;

public:
    std::string GetType()const { return m_type; };
    Player(unsigned char name, std::string&& type = "Player") :m_name(name), m_type(type), m_winTally(0), m_drawed(0) {}
    virtual unsigned char GetName()const { return m_name; }
    virtual bool ClaimSquare(std::map<int, unsigned char>& board, int move) = 0;
    virtual int NextMove(std::map<int, unsigned char>& board) = 0;
    virtual ~Player() = default;
    void AddWinToTally() { m_winTally++; }
    void Drawed() { m_drawed++; }
    int GetGameWins() const { return m_winTally; }
    int GetDraws() const { return m_drawed; }
};

class Human : public Player
{

public:
    Human(unsigned char name) :Player(name, "Human") {}
    virtual int NextMove(std::map<int, unsigned char>& board) override {
        int move;
        std::cout << "Enter a number on the board (e.g. 1): ";
        std::cin >> move;
        return move;
    }
    virtual bool ClaimSquare(std::map<int, unsigned char>& board, int move)
    {
        auto validSquare = std::find_if(board.begin(), board.end(), (&)(auto pair) {
            return pair.first == move;
            });
        if (validSquare != board.end())
        {
            if (validSquare->second == '-')
            {
                validSquare->second = Player::GetName();
                return true;
            }
            else
            {
                std::cout << "This square has already been claimed. Choose a different square!" << std::endl;
                return false;
            }
        }
        return false;
    }
    virtual ~Human() = default;
};

class Robot : public Player
{

public:
    Robot(unsigned char name) :Player(name, "Robot") {}

    bool CheckAvailability(std::map<int, unsigned char>& board, int number, std::vector<int>& keys) {
        for (auto& cell : board) {
            if (cell.first == number) {
                if (cell.second == '-') {
                    return true;
                }
            }
        }
        std::remove_if(keys.begin(), keys.end(), (&)(auto& key) {
            return key == number;
            });
        return false;
    }
    virtual int NextMove(std::map<int, unsigned char>& board) override
    {
        std::vector<int>number = { 1,2,3,4,5,6,7,8,9 };
        int randNum = 0;
        std::srand(std::time(0));
        do
        {
            randNum = rand() % 9 + 1;
        } 
        while (CheckAvailability(board, randNum, number) == false);
        return randNum;
    }
    virtual bool ClaimSquare(std::map<int, unsigned char>& board, int move)
    {
        auto validSquare = std::find_if(board.begin(), board.end(), (&)(auto pair) {
            return pair.first == move;
            });
        if (validSquare != board.end())
        {
            if (validSquare->second == '-')
            {
                validSquare->second = Player::GetName();
                return true;
            }
            else
            {
                std::cout << "This square has already been claimed. Choose a different square!" << std::endl;
                return false;
            }
        }
        return false;
    }
    virtual ~Robot() = default;
};

class NoughtsAndCrosses
{
private:

    //std::vector<Player*> m_p;
    std::map<int, unsigned char>board;
 
    void DisplayBoard()
    {

        for (auto const& cell : board)
        {
            if (cell.first % 3 == 1) {
                std::cout << "nn";
            }
            if (cell.second != '-') {
                std::cout << cell.second << "        ";
            }
            else
            {
                std::cout << cell.first << "        ";
            }
        }
        std::cout << "nn";
    }
    auto CheckForAWinner(std::map<int, unsigned char>& board, std::shared_ptr<Player>& player)
    {
        if (board.at(1) == player->GetName() && board.at(2) == player->GetName() && board.at(3) == player->GetName()) {
            return true;
        }
        else if (board.at(4) == player->GetName() && board.at(5) == player->GetName() && board.at(6) == player->GetName()) {
            return true;
        }
        else if (board.at(7) == player->GetName() && board.at(8) == player->GetName() && board.at(9) == player->GetName()) {
            return true;
        }
        else if (board.at(1) == player->GetName() && board.at(4) == player->GetName() && board.at(7) == player->GetName()) {
            return true;
        }
        else if (board.at(2) == player->GetName() && board.at(5) == player->GetName() && board.at(8) == player->GetName()) {
            return true;
        }
        else if (board.at(3) == player->GetName() && board.at(6) == player->GetName() && board.at(9) == player->GetName()) {
            return true;
        }
        else if (board.at(1) == player->GetName() && board.at(5) == player->GetName() && board.at(9) == player->GetName()) {
            return true;
        }
        else if (board.at(7) == player->GetName() && board.at(5) == player->GetName() && board.at(3) == player->GetName()) {
            return true;
        }
        else
        {
            return false;
        }
    }
    bool CheckForDraw(std::map<int, unsigned char>& board) {

        return std::all_of(board.begin(), board.end(), (&)(auto& pair) {return pair.second != '-'; });
    }
public:
    NoughtsAndCrosses()
    {
        board = { std::make_pair(1,'-'),std::make_pair(2,'-'),std::make_pair(3,'-'),
          std::make_pair(4,'-'),std::make_pair(5,'-'),std::make_pair(6,'-'),
          std::make_pair(7,'-'),std::make_pair(8,'-'),std::make_pair(9,'-') };
    }
    void ResetBoard() {
     
        std::for_each(board.begin(), board.end(), (&)(auto& pair) {
            pair.second = '-'; 
            });
        
    }
    auto play(std::shared_ptr<Player>& p1, std::shared_ptr<Player>& p2)
    {
        int currentPlayer = 1;
        bool isWinner = false;
        bool isDraw = false;

        std::vector<std::shared_ptr<Player>>m_player = { p1, p2 };
        do
        {
            currentPlayer = (currentPlayer + 1) % 2;
            do
            { 
               
              
               system("cls");
               std::cout << m_player.at(currentPlayer)->GetType() << ": " << m_player.at(currentPlayer)->GetName() << " turn: " << std::endl;
               DisplayBoard();
               system("pause");
               
               
               
            } 
            while (m_player.at(currentPlayer)->ClaimSquare(board, m_player.at(currentPlayer)->NextMove(board)) == false);
            
            //std::cout << "nPress enter to make the robot move. . .";
            //std::cin.get();
            //system("cls");
        } while (CheckForDraw(board) == false && (isWinner = CheckForAWinner(board, m_player.at(currentPlayer))) == false);
        
        
        if (isWinner == true)
        {
            return m_player.at(currentPlayer);
        }  
        m_player.at(0)->Drawed();
        m_player.at(1)->Drawed();
        DisplayBoard();
        ResetBoard();
        
        return std::shared_ptr<Player>(nullptr);
    }
    
};

int main() {


    std::shared_ptr<Player> human1 = std::make_shared<Human>('O');
    std::shared_ptr<Player> human2 = std::make_shared<Human>('X');
    std::shared_ptr<Player> robot1 = std::make_shared<Robot>('O');
    std::shared_ptr<Player> robot2 = std::make_shared<Robot>('X');
    std::vector<std::shared_ptr<Player>>player = { robot1, robot2 };
    NoughtsAndCrosses game;
    
    int round = 3;
    int roundCount = 0;
    std::shared_ptr<Player>winner;
    do 
    {
        
        int gameCount = 1;
        int totalGamesinRound = 3;
        std::cout << "START GAME!n";
        system("pause");
        system("cls");
        std::cout << "nROUND " << ++roundCount << ". . .n";
        do
        {
            std::cout << "Game " << gameCount << " of round " << roundCount << "n";
            winner = game.play(robot1, robot2);
            
            if (winner != std::shared_ptr<Player>(nullptr)) 
            {
                std::cout << "Winner of game " << gameCount << " is type: " << winner->GetType() << ": " << winner->GetName() << "n";
                winner->AddWinToTally();
            }
            else 
            {
                system("cls");
                std::cout << "Game " << gameCount << " is a draw!n";
                
            }
           
            gameCount++;
            totalGamesinRound--;
        } 
        while (totalGamesinRound != 0);

        /* std::cout << "Game 2: Human vs Robotn";
         game.play(robot1, robot1);*/
        std::cout << "Wins for " << robot1->GetType() << ": Player : " << robot1->GetName() << " - " << robot1->GetGameWins() << "n";
        std::cout << "Wins for " << robot2->GetType() << ": Player : " << robot2->GetName() << " - " << robot2->GetGameWins() << "n";
        std::cout << "Drawed: " << robot1->GetDraws() << "n";

        auto playerWithMostWins = std::max_element(player.begin(), player.end(),
            ()(const auto& lhs, const auto& rhs)
            {
                return lhs->GetGameWins() < rhs->GetGameWins();
            });

        std::cout << "Winner of round " << roundCount << " is " << playerWithMostWins->get()->GetName() << "n";
        round--;
    } 
    while (round != 0);
}

c++11 – C++ Queue Circular Array Implementation

I’m trying to implement a queue data structure in C++ using a circular array.

Please give recommendations on how I can improve this code.
Also, is my array growth strategy good? I’m doubling the array when the buffer is full.
(Try to remain in C++ 11 because, well that’s a restriction I have to follow atm).

Sorry for the lack of comments in advance LoL (this is a rushed implementation).

#include <iostream>
#include <utility>

template <typename T>
class Queue {
public:
    Queue() : data(nullptr), len(0), front(0), cap(0)
    {
    }

    ~Queue()
    {
        this->Clear();
    }

    Queue(const Queue& rhs) : Queue()
    {
        if (rhs.data) {
            this->data = new T(rhs.cap);
            this->cap = rhs.cap;
            this->len = rhs.len;
            this->front = rhs.front;

            for (size_t i = 0; i < len; ++i) {
                this->data(i) = rhs.data(i);
            }
        }
    }

    Queue(Queue&& rhs) : data(rhs.data), cap(rhs.cap), len(rhs.len), front(rhs.front)
    {
        rhs.data = nullptr;
    }

    Queue& operator=(Queue rhs)
    {
        swap(*this, rhs);
        return *this;
    }

    size_t GetLength() const { return len; }
    const T& GetFront() const { return data(front); }

    void Enqueue(const T& val)
    {
        if (len == cap) {
            size_t oldCap = cap;

            if (cap == 0) cap = 1;
            cap *= 2;

            T* newBuff = new T(cap);

            for (size_t i = 0; i < len; ++i) {
                size_t idx = (front + i) % oldCap;
                newBuff(i) = data(idx);
            }

            front = 0;
            data = newBuff;
        }

        data((front + len) % cap) = val;
        ++len;
    }

    T Dequeue()
    {
        T val = std::move(data(front));

        front = (front + 1) % cap;
        --len;
        return val;
    }

    void Clear()
    {
        delete() data;
        data = nullptr;
        this->cap = this->len = this->front = 0;
    }

    friend
    std::ostream& operator<< (std::ostream& out, const Queue& q)
    {
        out << "Queue{";
        for (size_t i = 0; i < q.len; ++i) {
            size_t idx = (q.front + i) % q.cap;
            out << q.data(idx);
            if (i < q.len - 1) out << ", ";
        }

        out << "}";

        return out;
    }

    friend
    void swap(Queue& lhs, Queue& rhs)
    {
        std::swap(lhs.data, rhs.data);
        std::swap(lhs.len, rhs.len);
        std::swap(lhs.cap, rhs.cap);
        std::swap(lhs.front, rhs.front);
    }

private:
    T* data;
    size_t len;
    size_t cap;
    size_t front;
};


int main()
{

    Queue < int > a;
    a.Enqeue( 5 ); // add 5 
    a.Enque ( 6 ); // add 6
    std::cout << a; // prints Queue{5, 6}
    
    a.Clear(); // empties the Queue
    std::cout << a; // prints Queue{}
}
```

c++11 – A FIR filter using Modern C++ features

I’m diving into “modern CPP”, with wide usage of templates and containers,
So I started with FIR filter.

In signal processing, a finite impulse response (FIR) filter is a filter whose impulse response (or response to any finite length input) is of finite duration, because it settles to zero in finite time. This is in contrast to infinite impulse response (IIR) filters, which may have internal feedback and may continue to respond indefinitely (usually decaying).

So I define FIR filter as a class and apply it to single scalar value or to the vector itself

Could you please review my code in terms of C++ coding?

#include <iostream>
#include <vector>
#include <list>
#include <algorithm>
#include <complex>
#include <cmath>
#include <iomanip>
#include <sstream>

// - Class method : operator(), constructor, various methods
// - Templates class and function
// - List and vector containers
// - Functors


template <typename T> std::string to_str(T & arr){
  std::ostringstream os;
  os << "(";  for (auto x: arr){    os<<" "<< x <<" ";  }  os << ")n"; 
  return os.str();
}

template <class T> class FIR { 
public: 
    std::vector< T > coeff;  // Array of coefficents is static all the time
    std::list< T > taps;  // Array of is are shifting each tick
    int order;

    FIR(std::vector< T > v)  
    { 
       coeff = v; 
       order = coeff.size();
       taps = std::list< T > (coeff.size(), 0);
    } 
    void reset(){
       taps = std::list< T > (coeff.size(), 0);
    }
    void append( T  x){
      taps.push_front( x);
      taps.pop_back();
    }

    auto sum_product(){
      T  psum = 0;
      typename   std::list< T >::iterator t;
      typename std::vector< T >::iterator c;
      // Can we do better here?
      for (   c =coeff.begin(),     t  =taps.begin(); 
              c!=coeff.end(),       t !=taps.end();
            ++c             ,     ++t             ){
        psum += (*c) * (*t);
      }
      return psum;
    }
    
    auto operator() ( T  x){
      append(x);
       T  psum = sum_product();
      return psum;
    }

     auto operator() (std::vector< T > x){
     std::vector< T > y( x.size(), 0);
     for (int i = 0; i<x.size(); ++i){
        y(i) =  operator()(x(i));
     }
     return y;
     }
}; 
  
int main() 
{ 
    std::vector<double> coeff = {0.0,1.0,5.0, 1.0, 0.0};
    
    FIR<double> fir(coeff); 
    std::cout <<"Coeff: " << to_str(fir.coeff);
    std::cout <<"Taps : "  << to_str(fir.taps);
    
    
    std::cout<<"nTRANSFORM IN THE LOOP n";
    std::vector<double> x_array = {0,1,2,3,4,5,6,0,0,0,0,0,0,13};
    for (auto x:x_array){
      auto p = fir(x);
      std::cout<<p<<"  ";
    }
    std::cout<<"n";
    fir.reset();

    std::cout<<"nTRANSFORM WITH FUNCTOR FOR SCALARn";
    std::vector<double> y_array( x_array.size(), 0);
    std::transform(x_array.begin(), x_array.end(), y_array.begin(), fir); 
    std::cout << to_str(y_array);
    fir.reset();

    std::cout<<"nAPPLY FUNCTOR FOR CONTTAINER n";
    auto y_2 = fir(x_array);
    std::cout << to_str(y_2);
    fir.reset();

    return 0; 
} 

c++11 – speed up a C++ code using openmp

How can i parallelize this following code using openmp:

int np = 1000000;
int maxkes = 100;

const double max_distance = 5.0;
double distance_thresh(maxkes+1) = {0};
for (kes = 1; kes <= maxkes; kes++){

    distance_thresh(kes) = max_distance / kes;
}

for (ies = 0; ies < np; ies++){
    for (jes = ies+1; jes < np; jes++){

        double dxp = xp(ies) - xp(jes);
        double dyp = yp(ies) - yp(jes);
        double dzp = zp(ies) - zp(jes);
        double distance = sqrt( dxp * dxp + dyp * dyp + dzp * dzp );
        double gps = gpx(ies) * gpx(jes) + gpy(ies) * gpy(jes) + gpz(ies) * gpz(jes);

        for (kes = 1; kes <= maxkes; kes++){

            if (distance < distance_thresh(kes)){
                double distan = kes * distance;
                E(kes) = E(kes) + gps * sin(distan) / distan;
            }
        }
    }
}

The calculation cost is very expensive because of three loops and two outside loops with size = 1000 000. I expect to receive some suggestions on parallel computing using OpenMP. To my knowledge, I know only #pragma omp parallel for reduction and #pragma omp parallel for.