Import string_bt from duckhandy
Modified to use std::make_index_sequence instead of the equivalent duckhandy utility.
This commit is contained in:
parent
751667769c
commit
f70899aed1
1 changed files with 128 additions and 0 deletions
128
src/wren/string_bt.hpp
Normal file
128
src/wren/string_bt.hpp
Normal file
|
@ -0,0 +1,128 @@
|
||||||
|
/* Copyright 2016-2018 Michele Santullo
|
||||||
|
* This file is part of "duckhandy".
|
||||||
|
*
|
||||||
|
* "duckhandy" is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* "duckhandy" is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with "duckhandy". If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef id170B0E6C34D14EBA9B92A35977BDBFB3
|
||||||
|
#define id170B0E6C34D14EBA9B92A35977BDBFB3
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
#include <cstddef>
|
||||||
|
#include <iostream>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
namespace dhandy {
|
||||||
|
namespace bt {
|
||||||
|
template <std::size_t S, typename Ch=char>
|
||||||
|
class string;
|
||||||
|
|
||||||
|
template <std::size_t S, typename Ch>
|
||||||
|
std::basic_ostream<Ch>& operator<< ( std::basic_ostream<Ch>& parStream, const string<S, Ch>& parString );
|
||||||
|
|
||||||
|
namespace implem {
|
||||||
|
template <std::size_t S, typename Ch> constexpr bool eq (const string<S, Ch>& l, const string<S, Ch>& r);
|
||||||
|
} //namespace implem
|
||||||
|
|
||||||
|
template <std::size_t S, typename Ch>
|
||||||
|
class string {
|
||||||
|
friend std::ostream& operator<< <>( std::ostream& parStream, const string<S>& parString );
|
||||||
|
friend constexpr bool implem::eq<S, Ch> (const string<S, Ch>&, const string<S, Ch>&);
|
||||||
|
public:
|
||||||
|
using value_type = Ch;
|
||||||
|
constexpr string ( const value_type* parString );
|
||||||
|
|
||||||
|
constexpr std::size_t size ( void ) const { return S - 1; }
|
||||||
|
template <std::size_t S2>
|
||||||
|
constexpr string<S + S2 - 1, Ch> operator+ ( const string<S2, Ch>& parOther ) const;
|
||||||
|
constexpr value_type operator[] ( std::size_t parIndex ) const;
|
||||||
|
constexpr bool operator== (const string<S, Ch>& other) const;
|
||||||
|
template <std::size_t S2> constexpr bool operator== (const string<S2, Ch>&) const { return false; }
|
||||||
|
|
||||||
|
template <typename... Args>
|
||||||
|
constexpr string ( Args... );
|
||||||
|
|
||||||
|
constexpr const value_type (&data_arr() const)[S] { return m_data; }
|
||||||
|
constexpr const value_type* data() const { return m_data; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
template <std::size_t... I>
|
||||||
|
constexpr string ( std::index_sequence<I...>, const value_type* parString );
|
||||||
|
|
||||||
|
const value_type m_data[S];
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace implem {
|
||||||
|
template <std::size_t S, std::size_t S2, std::size_t... I>
|
||||||
|
constexpr string<S + S2 - 1> concat ( std::index_sequence<I...>, const string<S>& parLeft, const string<S2>& parRight ) {
|
||||||
|
return string<S + S2 - 1>(
|
||||||
|
(I < S - 1 ? parLeft[I] : (I < S + S2 - 2 ? parRight[I - (S - 1)] : '\0'))...
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <> constexpr inline bool eq (const string<1>& l, const string<1>& r) { return l[0] == r[0]; }
|
||||||
|
template <std::size_t S, typename Ch>
|
||||||
|
constexpr inline bool eq (const string<S, Ch>& l, const string<S, Ch>& r) { return l[0] == r[0] and eq(string<S-1>(l.m_data+1), string<S-1>(r.m_data+1)); }
|
||||||
|
} //namespace implem
|
||||||
|
|
||||||
|
template <std::size_t S, typename Ch>
|
||||||
|
template <std::size_t... I>
|
||||||
|
constexpr string<S, Ch>::string (std::index_sequence<I...>, const value_type* parString) :
|
||||||
|
m_data{parString[I]...}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template <std::size_t S, typename Ch>
|
||||||
|
inline constexpr string<S, Ch>::string (const value_type* parString) :
|
||||||
|
string(std::make_index_sequence<S>(), parString)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template <std::size_t S, typename Ch>
|
||||||
|
template <typename... Args>
|
||||||
|
inline constexpr string<S, Ch>::string (Args... parArgs) :
|
||||||
|
m_data{parArgs...}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template <std::size_t S, typename Ch>
|
||||||
|
template <std::size_t S2>
|
||||||
|
constexpr inline string<S + S2 - 1, Ch> string<S, Ch>::operator+ (const string<S2, Ch>& parOther) const {
|
||||||
|
return implem::concat(std::make_index_sequence<S + S2 - 1>(), string<S>(m_data), parOther);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <std::size_t S, typename Ch>
|
||||||
|
inline std::ostream& operator<< (std::ostream& parStream, const string<S, Ch>& parString) {
|
||||||
|
parStream << parString.m_data;
|
||||||
|
return parStream;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <std::size_t S, typename Ch>
|
||||||
|
constexpr auto string<S, Ch>::operator[] (std::size_t parIndex) const -> value_type {
|
||||||
|
return (parIndex < S ? m_data[parIndex] : throw std::out_of_range(""));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <std::size_t S, typename Ch>
|
||||||
|
constexpr string<S, Ch> make_string (const Ch (&parData)[S]) {
|
||||||
|
return string<S>(parData);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <std::size_t S, typename Ch>
|
||||||
|
constexpr bool string<S, Ch>::operator== (const string<S, Ch>& other) const {
|
||||||
|
return implem::eq(*this, other);
|
||||||
|
}
|
||||||
|
} //namespace bt
|
||||||
|
} //namespace dhandy
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in a new issue