/// @file
/// @author David Pilger <dpilger26@gmail.com>
/// [GitHub Repository](https://github.com/dpilger26/NumCpp)
///
/// License
/// Copyright 2018-2023 David Pilger
///
/// Permission is hereby granted, free of charge, to any person obtaining a copy of this
/// software and associated documentation files(the "Software"), to deal in the Software
/// without restriction, including without limitation the rights to use, copy, modify,
/// merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
/// permit persons to whom the Software is furnished to do so, subject to the following
/// conditions :
///
/// The above copyright notice and this permission notice shall be included in all copies
/// or substantial portions of the Software.
///
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
/// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
/// PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
/// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
/// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
/// DEALINGS IN THE SOFTWARE.
///
/// Description
/// Holds 1D and 2D arrays, the main work horse of the NumCpp library
///
#pragma once
#include <array>
#include <cmath>
#include <deque>
#include <filesystem>
#include <forward_list>
#include <fstream>
#include <initializer_list>
#include <iostream>
#include <iterator>
#include <list>
#include <memory>
#include <numeric>
#include <set>
#include <string>
#include <type_traits>
#include <utility>
#include <vector>
#include "NumCpp/Core/Constants.hpp"
#include "NumCpp/Core/DtypeInfo.hpp"
#include "NumCpp/Core/Enums.hpp"
#include "NumCpp/Core/Internal/Endian.hpp"
#include "NumCpp/Core/Internal/Error.hpp"
#include "NumCpp/Core/Internal/StaticAsserts.hpp"
#include "NumCpp/Core/Internal/StdComplexOperators.hpp"
#include "NumCpp/Core/Internal/StlAlgorithms.hpp"
#include "NumCpp/Core/Internal/TypeTraits.hpp"
#include "NumCpp/Core/Shape.hpp"
#include "NumCpp/Core/Slice.hpp"
#include "NumCpp/Core/Types.hpp"
#include "NumCpp/NdArray/NdArrayIterators.hpp"
#include "NumCpp/Utils/essentiallyEqual.hpp"
#include "NumCpp/Utils/essentiallyEqualComplex.hpp"
#include "NumCpp/Utils/num2str.hpp"
#include "NumCpp/Utils/power.hpp"
#include "NumCpp/Utils/sqr.hpp"
#include "NumCpp/Utils/value2str.hpp"
namespace nc
{
namespace type_traits
{
//============================================================================
// Class Description:
/// Template class for determining if dtype is a valid index type for NdArray
///
template<typename>
struct is_ndarray_int : std::false_type
{
};
//============================================================================
// Class Description:
/// Template class for determining if dtype is a valid index typefor NdArray
///
template<typename dtype, typename Allocator>
struct is_ndarray_int<NdArray<dtype, Allocator>>
{
static constexpr bool value = std::is_integral_v<dtype>;
};
//============================================================================
// Class Description:
/// is_ndarray_int helper
///
template<typename T>
constexpr bool is_ndarray_int_v = is_ndarray_int<T>::value;
//============================================================================
// Class Description:
/// Template class for determining if dtype is an unsigned integer type
///
template<typename>
struct is_ndarray_signed_int : std::false_type
{
};
//============================================================================
// Class Description:
/// Template class for determining if dtype is an unsigned integer type
///
template<typename dtype, typename Allocator>
struct is_ndarray_signed_int<NdArray<dtype, Allocator>>
{
static constexpr bool value = std::is_signed_v<dtype>;
};
//============================================================================
// Class Description:
/// is_ndarray_int helper
///
template<typename T>
constexpr bool is_ndarray_signed_int_v = is_ndarray_signed_int<T>::value;
//============================================================================
// Class Description:
/// is_ndarray_int
///
template<typename T>
using ndarray_int_concept = std::enable_if_t<is_ndarray_int_v<T>, int>;
} // namespace type_traits
//================================================================================
// Class Description:
/// Holds 1D and 2D arrays, the main work horse of the NumCpp library
template<typename dtype, class Allocator = std::allocator<dtype>>
class NdArray
{
private:
STATIC_ASSERT_VALID_DTYPE(dtype);
static_assert(std::is_same_v<dtype, typename Allocator::value_type>,
"value_type and Allocator::value_type must match");
using AllocType = typename std::allocator_traits<Allocator>::template rebind_alloc<dtype>;
using AllocTraits = std::allocator_traits<AllocType>;
public:
using self_type = NdArray<dtype, Allocator>;
using value_type = dtype;
using allocator_type = Allocator;
using pointer = typename AllocTraits::pointer;
using const_pointer = typename AllocTraits::const_pointer;
using reference = dtype&;
using const_reference = const dtype&;
using size_type = uint32;
using index_type = int32;
using difference_type = typename AllocTraits::difference_type;
using iterator = NdArrayIterator<dtype, pointer, difference_type>;
using const_iterator = NdArrayConstIterator<dtype, const_pointer, difference_type>;
using reverse_iterator = std::reverse_iterator<iterator>;
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
using column_iterator = NdArrayColumnIterator<dtype, size_type, pointer, difference_type>;
using const_column_iterator = NdArrayConstColumnIterator<dtype, size_type, const_pointer, difference_type>;
using reverse_column_iterator = std::reverse_iterator<column_iterator>;
using const_reverse_column_iterator = std::reverse_iterator<const_column_iterator>;
//============================================================================
// Method Description:
/// Defualt Constructor, not very usefull...
///
NdArray() = default;
//============================================================================
// Method Description:
/// Constructor
///
/// @param inSquareSize: square number of rows and columns
///
explicit NdArray(size_type inSquareSize) :
shape_{ inSquareSize, inSquareSize },
size_{ inSquareSize * inSquareSize }
{
newArray();
}
//============================================================================
// Method Description:
/// Constructor
///
/// @param inNumRows
/// @param inNumCols
///
NdArray(size_type inNumRows, size_type inNumCols) :
shape_{ inNumRows, inNumCols },
size_{ inNumRows * inNumCols }
{
newArray();
}
//======