<commit_before>#pragma once

#include "vector.h"
#include "matrix.h"
#include "storage.h"

namespace nano
{
        template <typename tstorage, std::size_t trank>
        struct tensor_t;

        ///
        /// \brief tensor that owns the allocated memory.
        ///
        template <typename tscalar, std::size_t trank>
        using tensor_mem_t = tensor_t<tensor_vstorage_t<tscalar>, trank>;

        ///
        /// \brief tensor mapping a non-constant array.
        ///
        template <typename tscalar, std::size_t trank>
        using tensor_map_t = tensor_t<tensor_pstorage_t<tscalar>, trank>;

        ///
        /// \brief tensor mapping a constant array.
        ///
        template <typename tscalar, std::size_t trank>
        using tensor_cmap_t = tensor_t<tensor_pstorage_t<const tscalar>, trank>;

        ///
        /// \brief map non-constant data to tensors
        ///
        template <typename tscalar_, std::size_t trank>
        auto map_tensor(tscalar_* data, const tensor_dims_t<trank>& dims)
        {
                using tscalar = typename std::remove_const<tscalar_>::type;
                return tensor_map_t<tscalar, trank>(data, dims);
        }

        ///
        /// \brief map constant data to tensors
        ///
        template <typename tscalar_, std::size_t trank>
        auto map_tensor(const tscalar_* data, const tensor_dims_t<trank>& dims)
        {
                using tscalar = typename std::remove_const<tscalar_>::type;
                return tensor_cmap_t<tscalar, trank>(data, dims);
        }

        ///
        /// \brief map non-constant data to tensors
        ///
        template <typename tscalar_, typename... tsizes>
        auto map_tensor(tscalar_* data, const tsizes... dims)
        {
                return map_tensor(data, make_dims(dims...));
        }

        ///
        /// \brief map constant data to tensors
        ///
        template <typename tscalar_, typename... tsizes>
        auto map_tensor(const tscalar_* data, const tsizes... dims)
        {
                return map_tensor(data, make_dims(dims...));
        }

        ///
        /// \brief tensor.
        ///
        template <typename tstorage, std::size_t trank>
        struct tensor_t
        {
                using tdims = tensor_dims_t<trank>;
                using tscalar = typename tstorage::tscalar;
                using treference = typename tstorage::treference;
                using tconst_reference = typename tstorage::tconst_reference;

                using Index = tensor_size_t;    ///< for compatibility with Eigen
                using Scalar = tscalar;         ///< for compatibility with Eigen

                static_assert(trank >= 1, "cannot create tensors with fewer than one dimension");

                ///
                /// \brief constructor
                ///
                tensor_t()
                {
                        m_dims.fill(0);
                }

                ///
                /// \brief constructors that resize the storage to match the given size
                ///
                template <typename... tsizes>
                explicit tensor_t(const tsizes... dims) :
                        m_dims({dims...}),
                        m_storage(this->size())
                {
                        static_assert(tstorage::resizable(), "tensor not resizable");
                }

                explicit tensor_t(const tdims& dims) :
                        m_dims(dims),
                        m_storage(this->size())
                {
                        static_assert(tstorage::resizable(), "tensor not resizable");
                }

                ///
                /// \brief constructors that maps const or non-const arrays
                ///
                explicit tensor_t(tscalar* ptr, const tdims& dims) :
                        m_dims(dims),
                        m_storage(ptr)
                {
                        static_assert(!tstorage::resizable(), "tensor resizable");
                        assert(ptr != nullptr || !size());
                }

                explicit tensor_t(const tscalar* ptr, const tdims& dims) :
                        m_dims(dims),
                        m_storage(ptr)
                {
                        static_assert(!tstorage::resizable(), "tensor resizable");
                        assert(ptr != nullptr || !size());
                }

                ///
                /// \brief copy constructor
                ///
                tensor_t(const tensor_t&) = default;

                template <typename tstorage2>
                tensor_t(const tensor_t<tstorage2, trank>& other)
                {
                        static_assert(tstorage::resizable(), "tensor not resizable");
                        resize(other.dims());
                        array() = other.array();
                }<commit_msg>fix copy constructor for tensors<commit_after>#pragma once

#include "vector.h"
#include "matrix.h"
#include "storage.h"

namespace nano
{
        template <typename tstorage, std::size_t trank>
        struct tensor_t;

        ///
        /// \brief tensor that owns the allocated memory.
        ///
        template <typename tscalar, std::size_t trank>
        using tensor_mem_t = tensor_t<tensor_vstorage_t<tscalar>, trank>;

        ///
        /// \brief tensor mapping a non-constant array.
        ///
        template <typename tscalar, std::size_t trank>
        using tensor_map_t = tensor_t<tensor_pstorage_t<tscalar>, trank>;

        ///
        /// \brief tensor mapping a constant array.
        ///
        template <typename tscalar, std::size_t trank>
        using tensor_cmap_t = tensor_t<tensor_pstorage_t<const tscalar>, trank>;

        ///
        /// \brief map non-constant data to tensors
        ///
        template <typename tscalar_, std::size_t trank>
        auto map_tensor(tscalar_* data, const tensor_dims_t<trank>& dims)
        {
                using tscalar = typename std::remove_const<tscalar_>::type;
                return tensor_map_t<tscalar, trank>(data, dims);
        }

        ///
        /// \brief map constant data to tensors
        ///
        template <typename tscalar_, std::size_t trank>
        auto map_tensor(const tscalar_* data, const tensor_dims_t<trank>& dims)
        {
                using tscalar = typename std::remove_const<tscalar_>::type;
                return tensor_cmap_t<tscalar, trank>(data, dims);
        }

        ///
        /// \brief map non-constant data to tensors
        ///
        template <typename tscalar_, typename... tsizes>
        auto map_tensor(tscalar_* data, const tsizes... dims)
        {
                return map_tensor(data, make_dims(dims...));
        }

        ///
        /// \brief map constant data to tensors
        ///
        template <typename tscalar_, typename... tsizes>
        auto map_tensor(const tscalar_* data, const tsizes... dims)
        {
                return map_tensor(data, make_dims(dims...));
        }

        ///
        /// \brief tensor.
        ///
        template <typename tstorage, std::size_t trank>
        struct tensor_t
        {
                using tdims = tensor_dims_t<trank>;
                using tscalar = typename tstorage::tscalar;
                using treference = typename tstorage::treference;
                using tconst_reference = typename tstorage::tconst_reference;

                using Index = tensor_size_t;    ///< for compatibility with Eigen
                using Scalar = tscalar;         ///< for compatibility with Eigen

                static_assert(trank >= 1, "cannot create tensors with fewer than one dimension");

                ///
                /// \brief constructor
                ///
                tensor_t()
                {
                        m_dims.fill(0);
                }

                ///
                /// \brief constructors that resize the storage to match the given size
                ///
                template <typename... tsizes>
                explicit tensor_t(const tsizes... dims) :
                        m_dims({dims...}),
                        m_storage(this->size())
                {
                        static_assert(tstorage::resizable(), "tensor not resizable");
                }

                explicit tensor_t(const tdims& dims) :
                        m_dims(dims),
                        m_storage(this->size())
                {
                        static_assert(tstorage::resizable(), "tensor not resizable");
                }

                ///
                /// \brief constructors that maps const or non-const arrays
                ///
                explicit tensor_t(tscalar* ptr, const tdims& dims) :
                        m_dims(dims),
                        m_storage(ptr)
                {
                        static_assert(!tstorage::resizable(), "tensor resizable");
                        assert(ptr != nullptr || !size());
                }

                explicit tensor_t(const tscalar* ptr, const tdims& dims) :
                        m_dims(dims),
                        m_storage(ptr)
                {
                        static_assert(!tstorage::resizable(), "tensor resizable");
                        assert(ptr != nullptr || !size());
                }

                ///
                /// \brief copy constructor
                ///
                template <typename tstorage2>
                tensor_t(const tensor_t<tstorage2, trank>& other)
                {
                        if (tstorage::resizable())
                        {
                                resize(other.dims());
                                array() = other.array();
                        }
                        else
                        {
                                assert(dims() == other.dims());
                                array() = other.array();
                        }
                }
{'fraction_non_alphanumeric': 0.10288557213930348, 'fraction_numerical': 0.0007960199004975124, 'mean_word_length': 1.2310765815760267, 'pattern_counts': {'":': 0, '<': 57, '<?xml version=': 0, '>': 59, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2839326', 'n_tokens_mistral': 2605, 'n_tokens_neox': 2449, 'n_words': 604}