replace ArrayRange by tcb::span (reproduction of std::span)
This commit is contained in:
parent
4726542134
commit
d812cbd4d4
|
|
@ -201,7 +201,7 @@ class ConvertUTF8ToLocale
|
|||
{
|
||||
public:
|
||||
StringRange m_range;
|
||||
ConvertUTF8ToLocale( const char* string ) : m_range( StringRange( string, string + strlen( string ) ) ){
|
||||
ConvertUTF8ToLocale( const char* string ) : m_range( string, strlen( string ) ){
|
||||
}
|
||||
ConvertUTF8ToLocale( const StringRange& range ) : m_range( range ){
|
||||
}
|
||||
|
|
@ -214,7 +214,7 @@ inline TextOutputStreamType& ostream_write( TextOutputStreamType& ostream, const
|
|||
return ostream << convert.m_range;
|
||||
}
|
||||
|
||||
for ( const char* p = convert.m_range.first; p != convert.m_range.last; )
|
||||
for ( const char* p = convert.m_range.begin(); p != convert.m_range.end(); )
|
||||
{
|
||||
if ( !char_is_ascii( *p ) ) {
|
||||
UTF8Character c( p );
|
||||
|
|
@ -234,7 +234,7 @@ class ConvertLocaleToUTF8
|
|||
{
|
||||
public:
|
||||
StringRange m_range;
|
||||
ConvertLocaleToUTF8( const char* string ) : m_range( StringRange( string, string + strlen( string ) ) ){
|
||||
ConvertLocaleToUTF8( const char* string ) : m_range( string, strlen( string ) ){
|
||||
}
|
||||
ConvertLocaleToUTF8( const StringRange& range ) : m_range( range ){
|
||||
}
|
||||
|
|
@ -247,7 +247,7 @@ inline TextOutputStreamType& ostream_write( TextOutputStreamType& ostream, const
|
|||
return ostream << convert.m_range;
|
||||
}
|
||||
|
||||
for ( const char* p = convert.m_range.first; p != convert.m_range.last; ++p )
|
||||
for ( const char* p = convert.m_range.begin(); p != convert.m_range.end(); ++p )
|
||||
{
|
||||
if ( !char_is_ascii( *p ) ) {
|
||||
UTF8Character c( globalExtendedASCIICharacterSet().decode( *p ) );
|
||||
|
|
|
|||
|
|
@ -20,48 +20,10 @@
|
|||
*/
|
||||
|
||||
#pragma once
|
||||
#include "span.h"
|
||||
|
||||
/// \file
|
||||
/// \brief Macros for automatically converting a compile-time-sized array to a range.
|
||||
using tcb::Span;
|
||||
|
||||
template<typename Element>
|
||||
struct ArrayRange
|
||||
{
|
||||
typedef Element* Iterator;
|
||||
ArrayRange( Iterator first, Iterator last )
|
||||
: first( first ), last( last ){
|
||||
}
|
||||
Iterator first;
|
||||
Iterator last;
|
||||
};
|
||||
using StringArrayRange = Span<const char *const>;
|
||||
|
||||
template<typename Element>
|
||||
inline ArrayRange<Element> makeArrayRange( Element* first, Element* last ){
|
||||
return ArrayRange<Element>( first, last );
|
||||
}
|
||||
|
||||
template<typename Element>
|
||||
struct ArrayConstRange
|
||||
{
|
||||
typedef const Element* Iterator;
|
||||
ArrayConstRange( Iterator first, Iterator last )
|
||||
: first( first ), last( last ){
|
||||
}
|
||||
Iterator first;
|
||||
Iterator last;
|
||||
};
|
||||
|
||||
template<typename Element>
|
||||
inline ArrayConstRange<Element> makeArrayRange( const Element* first, const Element* last ){
|
||||
return ArrayConstRange<Element>( first, last );
|
||||
}
|
||||
|
||||
#define ARRAY_SIZE( array ) ( sizeof( array ) / sizeof( *array ) )
|
||||
#define ARRAY_END( array ) ( array + ARRAY_SIZE( array ) )
|
||||
#define ARRAY_RANGE( array ) ( makeArrayRange( array, ARRAY_END( array ) ) )
|
||||
|
||||
|
||||
typedef ArrayConstRange<const char*> StringArrayRange;
|
||||
#define STRING_ARRAY_RANGE( array ) ( StringArrayRange( array, ARRAY_END( array ) ) )
|
||||
|
||||
typedef ArrayRange<const char> StringRange;
|
||||
using StringRange = Span<const char>;
|
||||
|
|
|
|||
459
libs/generic/span.h
Normal file
459
libs/generic/span.h
Normal file
|
|
@ -0,0 +1,459 @@
|
|||
|
||||
/*
|
||||
This is an implementation of C++20's std::span
|
||||
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/n4820.pdf
|
||||
*/
|
||||
|
||||
// Copyright Tristan Brindle 2018.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file ../../LICENSE_1_0.txt or copy at
|
||||
// https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// https://github.com/tcbrindle/span/blob/master/include/tcb/span.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <type_traits>
|
||||
|
||||
#if !defined(NDEBUG)
|
||||
#include <stdexcept>
|
||||
#endif
|
||||
|
||||
namespace tcb {
|
||||
|
||||
// Establish default contract checking behavior
|
||||
#if !defined(NDEBUG)
|
||||
[[noreturn]] inline void contract_violation(const char* /*unused*/)
|
||||
{
|
||||
std::terminate();
|
||||
}
|
||||
#define TCB_SPAN_STRINGIFY(cond) #cond
|
||||
#define TCB_SPAN_EXPECT(cond) \
|
||||
cond ? (void) 0 : contract_violation("Expected " TCB_SPAN_STRINGIFY(cond))
|
||||
#else
|
||||
#define TCB_SPAN_EXPECT(cond)
|
||||
#endif
|
||||
|
||||
inline constexpr std::size_t dynamic_extent = SIZE_MAX;
|
||||
|
||||
template <typename ElementType, std::size_t Extent = dynamic_extent>
|
||||
class Span;
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename E, std::size_t S>
|
||||
struct span_storage {
|
||||
constexpr span_storage() noexcept = default;
|
||||
|
||||
constexpr span_storage(E* p_ptr, std::size_t /*unused*/) noexcept
|
||||
: ptr(p_ptr)
|
||||
{}
|
||||
|
||||
E* ptr = nullptr;
|
||||
static constexpr std::size_t size = S;
|
||||
};
|
||||
|
||||
template <typename E>
|
||||
struct span_storage<E, dynamic_extent> {
|
||||
constexpr span_storage() noexcept = default;
|
||||
|
||||
constexpr span_storage(E* p_ptr, std::size_t p_size) noexcept
|
||||
: ptr(p_ptr), size(p_size)
|
||||
{}
|
||||
|
||||
E* ptr = nullptr;
|
||||
std::size_t size = 0;
|
||||
};
|
||||
|
||||
|
||||
using std::data;
|
||||
using std::size;
|
||||
using std::void_t;
|
||||
|
||||
|
||||
template <typename T>
|
||||
using uncvref_t =
|
||||
typename std::remove_cv<typename std::remove_reference<T>::type>::type;
|
||||
|
||||
template <typename>
|
||||
struct is_span : std::false_type {};
|
||||
|
||||
template <typename T, std::size_t S>
|
||||
struct is_span<Span<T, S>> : std::true_type {};
|
||||
|
||||
template <typename>
|
||||
struct is_std_array : std::false_type {};
|
||||
|
||||
template <typename T, std::size_t N>
|
||||
struct is_std_array<std::array<T, N>> : std::true_type {};
|
||||
|
||||
template <typename, typename = void>
|
||||
struct has_size_and_data : std::false_type {};
|
||||
|
||||
template <typename T>
|
||||
struct has_size_and_data<T, void_t<decltype(detail::size(std::declval<T>())),
|
||||
decltype(detail::data(std::declval<T>()))>>
|
||||
: std::true_type {};
|
||||
|
||||
template <typename C, typename U = uncvref_t<C>>
|
||||
struct is_container {
|
||||
static constexpr bool value =
|
||||
!is_span<U>::value && !is_std_array<U>::value &&
|
||||
!std::is_array<U>::value && has_size_and_data<C>::value;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
using remove_pointer_t = typename std::remove_pointer<T>::type;
|
||||
|
||||
template <typename, typename, typename = void>
|
||||
struct is_container_element_type_compatible : std::false_type {};
|
||||
|
||||
template <typename T, typename E>
|
||||
struct is_container_element_type_compatible<
|
||||
T, E,
|
||||
typename std::enable_if<
|
||||
!std::is_same<typename std::remove_cv<decltype(
|
||||
detail::data(std::declval<T>()))>::type,
|
||||
void>::value>::type>
|
||||
: std::is_convertible<
|
||||
remove_pointer_t<decltype(detail::data(std::declval<T>()))> (*)[],
|
||||
E (*)[]> {};
|
||||
|
||||
template <typename, typename = size_t>
|
||||
struct is_complete : std::false_type {};
|
||||
|
||||
template <typename T>
|
||||
struct is_complete<T, decltype(sizeof(T))> : std::true_type {};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <typename ElementType, std::size_t Extent>
|
||||
class Span {
|
||||
static_assert(std::is_object<ElementType>::value,
|
||||
"A span's ElementType must be an object type (not a "
|
||||
"reference type or void)");
|
||||
static_assert(detail::is_complete<ElementType>::value,
|
||||
"A span's ElementType must be a complete type (not a forward "
|
||||
"declaration)");
|
||||
static_assert(!std::is_abstract<ElementType>::value,
|
||||
"A span's ElementType cannot be an abstract class type");
|
||||
|
||||
using storage_type = detail::span_storage<ElementType, Extent>;
|
||||
|
||||
public:
|
||||
// constants and types
|
||||
using element_type = ElementType;
|
||||
using value_type = typename std::remove_cv<ElementType>::type;
|
||||
using size_type = std::size_t;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using pointer = element_type*;
|
||||
using const_pointer = const element_type*;
|
||||
using reference = element_type&;
|
||||
using const_reference = const element_type&;
|
||||
using iterator = pointer;
|
||||
using reverse_iterator = std::reverse_iterator<iterator>;
|
||||
|
||||
static constexpr size_type extent = Extent;
|
||||
|
||||
// [span.cons], span constructors, copy, assignment, and destructor
|
||||
template <
|
||||
std::size_t E = Extent,
|
||||
typename std::enable_if<(E == dynamic_extent || E <= 0), int>::type = 0>
|
||||
constexpr Span() noexcept
|
||||
{}
|
||||
|
||||
constexpr Span(pointer ptr, size_type count)
|
||||
: storage_(ptr, count)
|
||||
{
|
||||
TCB_SPAN_EXPECT(extent == dynamic_extent || count == extent);
|
||||
}
|
||||
|
||||
constexpr Span(pointer first_elem, pointer last_elem)
|
||||
: storage_(first_elem, last_elem - first_elem)
|
||||
{
|
||||
TCB_SPAN_EXPECT(extent == dynamic_extent ||
|
||||
last_elem - first_elem ==
|
||||
static_cast<std::ptrdiff_t>(extent));
|
||||
}
|
||||
|
||||
template <std::size_t N, std::size_t E = Extent,
|
||||
typename std::enable_if<
|
||||
(E == dynamic_extent || N == E) &&
|
||||
detail::is_container_element_type_compatible<
|
||||
element_type (&)[N], ElementType>::value,
|
||||
int>::type = 0>
|
||||
constexpr Span(element_type (&arr)[N]) noexcept : storage_(arr, N)
|
||||
{}
|
||||
|
||||
template <std::size_t N, std::size_t E = Extent,
|
||||
typename std::enable_if<
|
||||
(E == dynamic_extent || N == E) &&
|
||||
detail::is_container_element_type_compatible<
|
||||
std::array<value_type, N>&, ElementType>::value,
|
||||
int>::type = 0>
|
||||
constexpr Span(std::array<value_type, N>& arr) noexcept
|
||||
: storage_(arr.data(), N)
|
||||
{}
|
||||
|
||||
template <std::size_t N, std::size_t E = Extent,
|
||||
typename std::enable_if<
|
||||
(E == dynamic_extent || N == E) &&
|
||||
detail::is_container_element_type_compatible<
|
||||
const std::array<value_type, N>&, ElementType>::value,
|
||||
int>::type = 0>
|
||||
constexpr Span(const std::array<value_type, N>& arr) noexcept
|
||||
: storage_(arr.data(), N)
|
||||
{}
|
||||
|
||||
template <
|
||||
typename Container, std::size_t E = Extent,
|
||||
typename std::enable_if<
|
||||
E == dynamic_extent && detail::is_container<Container>::value &&
|
||||
detail::is_container_element_type_compatible<
|
||||
Container&, ElementType>::value,
|
||||
int>::type = 0>
|
||||
constexpr Span(Container& cont)
|
||||
: storage_(detail::data(cont), detail::size(cont))
|
||||
{}
|
||||
|
||||
template <
|
||||
typename Container, std::size_t E = Extent,
|
||||
typename std::enable_if<
|
||||
E == dynamic_extent && detail::is_container<Container>::value &&
|
||||
detail::is_container_element_type_compatible<
|
||||
const Container&, ElementType>::value,
|
||||
int>::type = 0>
|
||||
constexpr Span(const Container& cont)
|
||||
: storage_(detail::data(cont), detail::size(cont))
|
||||
{}
|
||||
|
||||
constexpr Span(const Span& other) noexcept = default;
|
||||
|
||||
template <typename OtherElementType, std::size_t OtherExtent,
|
||||
typename std::enable_if<
|
||||
(Extent == OtherExtent || Extent == dynamic_extent) &&
|
||||
std::is_convertible<OtherElementType (*)[],
|
||||
ElementType (*)[]>::value,
|
||||
int>::type = 0>
|
||||
constexpr Span(const Span<OtherElementType, OtherExtent>& other) noexcept
|
||||
: storage_(other.data(), other.size())
|
||||
{}
|
||||
|
||||
~Span() noexcept = default;
|
||||
|
||||
constexpr Span&
|
||||
operator=(const Span& other) noexcept = default;
|
||||
|
||||
// [span.sub], span subviews
|
||||
template <std::size_t Count>
|
||||
constexpr Span<element_type, Count> first() const
|
||||
{
|
||||
TCB_SPAN_EXPECT(Count <= size());
|
||||
return {data(), Count};
|
||||
}
|
||||
|
||||
template <std::size_t Count>
|
||||
constexpr Span<element_type, Count> last() const
|
||||
{
|
||||
TCB_SPAN_EXPECT(Count <= size());
|
||||
return {data() + (size() - Count), Count};
|
||||
}
|
||||
|
||||
template <std::size_t Offset, std::size_t Count = dynamic_extent>
|
||||
using subspan_return_t =
|
||||
Span<ElementType, Count != dynamic_extent
|
||||
? Count
|
||||
: (Extent != dynamic_extent ? Extent - Offset
|
||||
: dynamic_extent)>;
|
||||
|
||||
template <std::size_t Offset, std::size_t Count = dynamic_extent>
|
||||
constexpr subspan_return_t<Offset, Count> subspan() const
|
||||
{
|
||||
TCB_SPAN_EXPECT(Offset <= size() &&
|
||||
(Count == dynamic_extent || Offset + Count <= size()));
|
||||
return {data() + Offset,
|
||||
Count != dynamic_extent ? Count : size() - Offset};
|
||||
}
|
||||
|
||||
constexpr Span<element_type, dynamic_extent>
|
||||
first(size_type count) const
|
||||
{
|
||||
TCB_SPAN_EXPECT(count <= size());
|
||||
return {data(), count};
|
||||
}
|
||||
|
||||
constexpr Span<element_type, dynamic_extent>
|
||||
last(size_type count) const
|
||||
{
|
||||
TCB_SPAN_EXPECT(count <= size());
|
||||
return {data() + (size() - count), count};
|
||||
}
|
||||
|
||||
constexpr Span<element_type, dynamic_extent>
|
||||
subspan(size_type offset, size_type count = dynamic_extent) const
|
||||
{
|
||||
TCB_SPAN_EXPECT(offset <= size() &&
|
||||
(count == dynamic_extent || offset + count <= size()));
|
||||
return {data() + offset,
|
||||
count == dynamic_extent ? size() - offset : count};
|
||||
}
|
||||
|
||||
// [span.obs], span observers
|
||||
constexpr size_type size() const noexcept { return storage_.size; }
|
||||
|
||||
constexpr size_type size_bytes() const noexcept
|
||||
{
|
||||
return size() * sizeof(element_type);
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr bool empty() const noexcept
|
||||
{
|
||||
return size() == 0;
|
||||
}
|
||||
|
||||
// [span.elem], span element access
|
||||
constexpr reference operator[](size_type idx) const
|
||||
{
|
||||
TCB_SPAN_EXPECT(idx < size());
|
||||
return *(data() + idx);
|
||||
}
|
||||
|
||||
constexpr reference front() const
|
||||
{
|
||||
TCB_SPAN_EXPECT(!empty());
|
||||
return *data();
|
||||
}
|
||||
|
||||
constexpr reference back() const
|
||||
{
|
||||
TCB_SPAN_EXPECT(!empty());
|
||||
return *(data() + (size() - 1));
|
||||
}
|
||||
|
||||
constexpr pointer data() const noexcept { return storage_.ptr; }
|
||||
|
||||
// [span.iterators], span iterator support
|
||||
constexpr iterator begin() const noexcept { return data(); }
|
||||
|
||||
constexpr iterator end() const noexcept { return data() + size(); }
|
||||
|
||||
constexpr reverse_iterator rbegin() const noexcept
|
||||
{
|
||||
return reverse_iterator(end());
|
||||
}
|
||||
|
||||
constexpr reverse_iterator rend() const noexcept
|
||||
{
|
||||
return reverse_iterator(begin());
|
||||
}
|
||||
|
||||
private:
|
||||
storage_type storage_{};
|
||||
};
|
||||
|
||||
|
||||
/* Deduction Guides */
|
||||
template <class T, size_t N>
|
||||
Span(T (&)[N])->Span<T, N>;
|
||||
|
||||
template <class T, size_t N>
|
||||
Span(std::array<T, N>&)->Span<T, N>;
|
||||
|
||||
template <class T, size_t N>
|
||||
Span(const std::array<T, N>&)->Span<const T, N>;
|
||||
|
||||
template <class Container>
|
||||
Span(Container&)->Span<typename Container::value_type>;
|
||||
|
||||
template <class Container>
|
||||
Span(const Container&)->Span<const typename Container::value_type>;
|
||||
|
||||
|
||||
template <typename ElementType, std::size_t Extent>
|
||||
constexpr Span<ElementType, Extent>
|
||||
make_span(Span<ElementType, Extent> s) noexcept
|
||||
{
|
||||
return s;
|
||||
}
|
||||
|
||||
template <typename T, std::size_t N>
|
||||
constexpr Span<T, N> make_span(T (&arr)[N]) noexcept
|
||||
{
|
||||
return {arr};
|
||||
}
|
||||
|
||||
template <typename T, std::size_t N>
|
||||
constexpr Span<T, N> make_span(std::array<T, N>& arr) noexcept
|
||||
{
|
||||
return {arr};
|
||||
}
|
||||
|
||||
template <typename T, std::size_t N>
|
||||
constexpr Span<const T, N>
|
||||
make_span(const std::array<T, N>& arr) noexcept
|
||||
{
|
||||
return {arr};
|
||||
}
|
||||
|
||||
template <typename Container>
|
||||
constexpr Span<typename Container::value_type> make_span(Container& cont)
|
||||
{
|
||||
return {cont};
|
||||
}
|
||||
|
||||
template <typename Container>
|
||||
constexpr Span<const typename Container::value_type>
|
||||
make_span(const Container& cont)
|
||||
{
|
||||
return {cont};
|
||||
}
|
||||
|
||||
template <typename ElementType, std::size_t Extent>
|
||||
Span<const std::byte, ((Extent == dynamic_extent) ? dynamic_extent
|
||||
: sizeof(ElementType) * Extent)>
|
||||
as_bytes(Span<ElementType, Extent> s) noexcept
|
||||
{
|
||||
return {reinterpret_cast<const std::byte*>(s.data()), s.size_bytes()};
|
||||
}
|
||||
|
||||
template <
|
||||
class ElementType, size_t Extent,
|
||||
typename std::enable_if<!std::is_const<ElementType>::value, int>::type = 0>
|
||||
Span<std::byte, ((Extent == dynamic_extent) ? dynamic_extent
|
||||
: sizeof(ElementType) * Extent)>
|
||||
as_writable_bytes(Span<ElementType, Extent> s) noexcept
|
||||
{
|
||||
return {reinterpret_cast<std::byte*>(s.data()), s.size_bytes()};
|
||||
}
|
||||
|
||||
template <std::size_t N, typename E, std::size_t S>
|
||||
constexpr auto get(Span<E, S> s) -> decltype(s[N])
|
||||
{
|
||||
return s[N];
|
||||
}
|
||||
|
||||
} // namespace tcb
|
||||
|
||||
namespace std {
|
||||
|
||||
template <typename ElementType, size_t Extent>
|
||||
class tuple_size<tcb::Span<ElementType, Extent>>
|
||||
: public integral_constant<size_t, Extent> {};
|
||||
|
||||
template <typename ElementType>
|
||||
class tuple_size<tcb::Span<
|
||||
ElementType, tcb::dynamic_extent>>; // not defined
|
||||
|
||||
template <size_t I, typename ElementType, size_t Extent>
|
||||
class tuple_element<I, tcb::Span<ElementType, Extent>> {
|
||||
public:
|
||||
static_assert(Extent != tcb::dynamic_extent &&
|
||||
I < Extent,
|
||||
"");
|
||||
using type = ElementType;
|
||||
};
|
||||
|
||||
} // end namespace std
|
||||
|
|
@ -186,9 +186,9 @@ RadioHBox RadioHBox_new( StringArrayRange names ){
|
|||
gtk_widget_show( GTK_WIDGET( hbox ) );
|
||||
|
||||
GtkRadioButton* radio = 0;
|
||||
for ( StringArrayRange::Iterator i = names.first; i != names.last; ++i )
|
||||
for ( const char *name : names )
|
||||
{
|
||||
radio = GTK_RADIO_BUTTON( gtk_radio_button_new_with_label_from_widget( radio, *i ) );
|
||||
radio = GTK_RADIO_BUTTON( gtk_radio_button_new_with_label_from_widget( radio, name ) );
|
||||
gtk_widget_show( GTK_WIDGET( radio ) );
|
||||
gtk_box_pack_start( GTK_BOX( hbox ), GTK_WIDGET( radio ), FALSE, FALSE, 0 );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -230,25 +230,24 @@ inline StringRange PathFilenameless( const char *path ){
|
|||
class PathCleaned
|
||||
{
|
||||
public:
|
||||
const char* m_path;
|
||||
const char* m_end;
|
||||
PathCleaned( const char* path ) : m_path( path ), m_end( path + std::strlen( path ) ){
|
||||
const StringRange m_path;
|
||||
PathCleaned( const char* path ) : m_path( path, std::strlen( path ) ){
|
||||
}
|
||||
PathCleaned( const StringRange& range ) : m_path( range.first ), m_end( range.last ){
|
||||
PathCleaned( const StringRange& range ) : m_path( range ){
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Writes \p path to \p ostream with dos-style separators replaced by unix-style separators.
|
||||
template<typename TextOutputStreamType>
|
||||
TextOutputStreamType& ostream_write( TextOutputStreamType& ostream, const PathCleaned& path ){
|
||||
for ( const char* i = path.m_path; i != path.m_end; ++i )
|
||||
for ( const char c : path.m_path )
|
||||
{
|
||||
if ( *i == '\\' ) {
|
||||
if ( c == '\\' ) {
|
||||
ostream << '/';
|
||||
}
|
||||
else
|
||||
{
|
||||
ostream << *i;
|
||||
ostream << c;
|
||||
}
|
||||
}
|
||||
return ostream;
|
||||
|
|
@ -300,7 +299,7 @@ template<typename TextOutputStreamType, typename SRC>
|
|||
TextOutputStreamType& ostream_write( TextOutputStreamType& ostream, const PathDefaultExtension<SRC>& path ){
|
||||
ostream << path.m_path;
|
||||
if constexpr ( std::is_same_v<SRC, PathCleaned> ){
|
||||
if( strEmpty( path_get_extension( path.m_path.m_path ) ) )
|
||||
if( strEmpty( path_get_extension( path.m_path.m_path.data() ) ) )
|
||||
ostream << path.m_extension;
|
||||
}
|
||||
else if constexpr ( std::is_same_v<SRC, const char*> ){
|
||||
|
|
|
|||
|
|
@ -281,7 +281,7 @@ inline TextOutputStreamType& ostream_write( TextOutputStreamType& ostream, const
|
|||
/// \brief Writes a \p range of characters to \p ostream.
|
||||
template<typename TextOutputStreamType>
|
||||
inline TextOutputStreamType& ostream_write( TextOutputStreamType& ostream, const StringRange& range ){
|
||||
ostream.write( range.first, range.last - range.first );
|
||||
ostream.write( range.data(), range.size() );
|
||||
return ostream;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -212,9 +212,8 @@ inline char* string_clone( const char* other, Allocator& allocator ){
|
|||
/// The returned buffer must be released with \c string_release using a matching \p allocator.
|
||||
template<typename Allocator>
|
||||
inline char* string_clone_range( StringRange range, Allocator& allocator ){
|
||||
std::size_t length = range.last - range.first;
|
||||
char* copied = strncpy( string_new( length, allocator ), range.first, length );
|
||||
copied[length] = '\0';
|
||||
char* copied = strncpy( string_new( range.size(), allocator ), range.data(), range.size() );
|
||||
copied[range.size()] = '\0';
|
||||
return copied;
|
||||
}
|
||||
|
||||
|
|
@ -504,9 +503,9 @@ class SmartBuffer : private Allocator
|
|||
char* m_buffer;
|
||||
|
||||
char* copy_range( StringRange range ){
|
||||
char* buffer = Allocator::allocate( sizeof( std::size_t ) + ( range.last - range.first ) + 1 );
|
||||
strncpy( buffer + sizeof( std::size_t ), range.first, range.last - range.first );
|
||||
buffer[sizeof( std::size_t ) + ( range.last - range.first )] = '\0';
|
||||
char* buffer = Allocator::allocate( sizeof( std::size_t ) + range.size() + 1 );
|
||||
strncpy( buffer + sizeof( std::size_t ), range.data(), range.size() );
|
||||
buffer[sizeof( std::size_t ) + range.size()] = '\0';
|
||||
*reinterpret_cast<std::size_t*>( buffer ) = 0;
|
||||
return buffer;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -122,7 +122,7 @@ class XMLSAXImporter
|
|||
}
|
||||
static void characters( void *user_data, const xmlChar *ch, int len ){
|
||||
reinterpret_cast<XMLSAXImporter*>( user_data )->m_importer
|
||||
<< StringRange( reinterpret_cast<const char*>( ch ), reinterpret_cast<const char*>( ch + len ) );
|
||||
<< StringRange( reinterpret_cast<const char*>( ch ), len );
|
||||
}
|
||||
|
||||
static void warning( void *user_data, const char *msg, ... ){
|
||||
|
|
|
|||
|
|
@ -106,7 +106,7 @@ class XMLStreamWriter : public XMLImporter, public XMLAttrVisitor
|
|||
std::vector<state_t> m_elements;
|
||||
|
||||
void write_cdata( const char* buffer, std::size_t length ){
|
||||
m_ostream << StringRange( buffer, buffer + length );
|
||||
m_ostream << StringRange( buffer, length );
|
||||
}
|
||||
void write_string( const char* string ){
|
||||
m_ostream << string;
|
||||
|
|
|
|||
|
|
@ -511,30 +511,27 @@ inline void parseToken( Tokeniser& tokeniser, const char* token ){
|
|||
ASSERT_MESSAGE( Tokeniser_parseToken( tokeniser, token ), "error parsing vmf: token not found: " << makeQuoted( token ) );
|
||||
}
|
||||
|
||||
#include "generic/arrayrange.h"
|
||||
|
||||
class VMFBlock;
|
||||
typedef ArrayConstRange<VMFBlock> VMFBlockArrayRange;
|
||||
|
||||
|
||||
class VMFBlock
|
||||
{
|
||||
public:
|
||||
using VMFBlockArray = std::vector<const VMFBlock*>;
|
||||
const char* m_name;
|
||||
VMFBlockArrayRange m_children;
|
||||
typedef const VMFBlock Value;
|
||||
VMFBlockArray m_children;
|
||||
|
||||
VMFBlock( const char* name, VMFBlockArrayRange children = VMFBlockArrayRange( 0, 0 ) ) : m_name( name ), m_children( children ){
|
||||
VMFBlock( const char* name, VMFBlockArray children = VMFBlockArray() ) : m_name( name ), m_children( children ){
|
||||
}
|
||||
const char* name() const {
|
||||
return m_name;
|
||||
}
|
||||
typedef Value* const_iterator;
|
||||
|
||||
using const_iterator = VMFBlockArray::const_iterator;
|
||||
const_iterator begin() const {
|
||||
return m_children.first;
|
||||
return m_children.begin();
|
||||
}
|
||||
const_iterator end() const {
|
||||
return m_children.last;
|
||||
return m_children.end();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -545,36 +542,28 @@ const VMFBlock c_vmfOffsetNormals( "offset_normals" );
|
|||
const VMFBlock c_vmfAlphas( "alphas" );
|
||||
const VMFBlock c_vmfTriangleTags( "triangle_tags" );
|
||||
const VMFBlock c_vmfAllowedVerts( "allowed_verts" );
|
||||
const VMFBlock c_vmfDispInfoChildren[] = { c_vmfNormals, c_vmfDistances, c_vmfOffsets, c_vmfOffsetNormals, c_vmfAlphas, c_vmfTriangleTags, c_vmfAllowedVerts };
|
||||
const VMFBlock c_vmfDispInfo( "dispinfo", ARRAY_RANGE( c_vmfDispInfoChildren ) );
|
||||
const VMFBlock c_vmfSideChildren[] = { c_vmfDispInfo };
|
||||
const VMFBlock c_vmfSide( "side", ARRAY_RANGE( c_vmfSideChildren ) );
|
||||
const VMFBlock c_vmfDispInfo( "dispinfo", { &c_vmfNormals, &c_vmfDistances, &c_vmfOffsets, &c_vmfOffsetNormals, &c_vmfAlphas, &c_vmfTriangleTags, &c_vmfAllowedVerts } );
|
||||
const VMFBlock c_vmfSide( "side", { &c_vmfDispInfo } );
|
||||
const VMFBlock c_vmfEditor( "editor" );
|
||||
const VMFBlock c_vmfVersionInfo( "versioninfo" );
|
||||
const VMFBlock c_vmfViewSettings( "viewsettings" );
|
||||
const VMFBlock c_vmfCordon( "cordon" );
|
||||
const VMFBlock c_vmfGroupChildren[] = { c_vmfEditor };
|
||||
const VMFBlock c_vmfGroup( "group", ARRAY_RANGE( c_vmfGroupChildren ) );
|
||||
const VMFBlock c_vmfGroup( "group", { &c_vmfEditor } );
|
||||
const VMFBlock c_vmfCamera( "camera" );
|
||||
const VMFBlock c_vmfCamerasChildren[] = { c_vmfCamera };
|
||||
const VMFBlock c_vmfCameras( "cameras", ARRAY_RANGE( c_vmfCamerasChildren ) );
|
||||
const VMFBlock c_vmfCameras( "cameras", { &c_vmfCamera } );
|
||||
VMFBlock c_vmfVisGroup( "visgroup" );
|
||||
VMFBlock c_vmfVisGroups( "visgroups", VMFBlockArrayRange( &c_vmfVisGroup, &c_vmfVisGroup + 1 ) );
|
||||
const VMFBlock c_vmfSolidChildren[] = { c_vmfSide, c_vmfEditor };
|
||||
const VMFBlock c_vmfSolid( "solid", ARRAY_RANGE( c_vmfSolidChildren ) );
|
||||
const VMFBlock c_vmfVisGroups( "visgroups", { &c_vmfVisGroup } );
|
||||
const VMFBlock c_vmfSolid( "solid", { &c_vmfSide, &c_vmfEditor } );
|
||||
const VMFBlock c_vmfConnections( "connections" );
|
||||
const VMFBlock c_vmfEntityChildren[] = { c_vmfEditor, c_vmfSolid, c_vmfGroup, c_vmfConnections };
|
||||
const VMFBlock c_vmfEntity( "entity", ARRAY_RANGE( c_vmfEntityChildren ) );
|
||||
const VMFBlock c_vmfWorldChildren[] = { c_vmfEditor, c_vmfSolid, c_vmfGroup };
|
||||
const VMFBlock c_vmfWorld( "world", ARRAY_RANGE( c_vmfWorldChildren ) );
|
||||
const VMFBlock c_vmfRootChildren[] = { c_vmfVersionInfo, c_vmfViewSettings, c_vmfVisGroups, c_vmfWorld, c_vmfEntity, c_vmfCameras, c_vmfCordon };
|
||||
const VMFBlock c_vmfRoot( "", ARRAY_RANGE( c_vmfRootChildren ) );
|
||||
const VMFBlock c_vmfEntity( "entity", { &c_vmfEditor, &c_vmfSolid, &c_vmfGroup, &c_vmfConnections } );
|
||||
const VMFBlock c_vmfWorld( "world", { &c_vmfEditor, &c_vmfSolid, &c_vmfGroup } );
|
||||
const VMFBlock c_vmfRoot( "", { &c_vmfVersionInfo, &c_vmfViewSettings, &c_vmfVisGroups, &c_vmfWorld, &c_vmfEntity, &c_vmfCameras, &c_vmfCordon } );
|
||||
|
||||
class VMFInit
|
||||
{
|
||||
public:
|
||||
VMFInit(){
|
||||
c_vmfVisGroup.m_children = VMFBlockArrayRange( &c_vmfVisGroup, &c_vmfVisGroup + 1 );
|
||||
c_vmfVisGroup.m_children = { &c_vmfVisGroup };
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -586,7 +575,7 @@ int g_vmf_brushes;
|
|||
inline VMFBlock::const_iterator VMFBlock_find( const VMFBlock& block, const char* name ){
|
||||
for ( VMFBlock::const_iterator i = block.begin(); i != block.end(); ++i )
|
||||
{
|
||||
if ( string_equal( name, ( *i ).name() ) ) {
|
||||
if ( string_equal( name, ( *i )->name() ) ) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
|
@ -614,7 +603,7 @@ void VMF_parseBlock( Tokeniser& tokeniser, const VMFBlock& block ){
|
|||
else if ( string_equal( tmp.c_str(), "entity" ) || string_equal( tmp.c_str(), "world" ) ) {
|
||||
++g_vmf_entities;
|
||||
}
|
||||
VMF_parseBlock( tokeniser, *i );
|
||||
VMF_parseBlock( tokeniser, **i );
|
||||
parseToken( tokeniser, "}" );
|
||||
tokeniser.nextLine();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ void Brush_constructPreferences( PreferencesPage& page ){
|
|||
page.appendCombo(
|
||||
"New map Brush Type",
|
||||
g_brushType,
|
||||
STRING_ARRAY_RANGE( names )
|
||||
StringArrayRange( names )
|
||||
);
|
||||
}
|
||||
// d1223m
|
||||
|
|
|
|||
|
|
@ -2519,7 +2519,7 @@ void Camera_constructPreferences( PreferencesPage& page ){
|
|||
const char* render_modes[]{ "Wireframe", "Flatshade", "Textured", "Textured+Wire", "Lighting" };
|
||||
page.appendCombo(
|
||||
"Render Mode",
|
||||
StringArrayRange( render_modes, render_modes + ARRAY_SIZE( render_modes ) - ( g_pGameDescription->mGameType == "doom3"? 0 : 1 ) ),
|
||||
StringArrayRange( render_modes, std::size( render_modes ) - ( g_pGameDescription->mGameType == "doom3"? 0 : 1 ) ),
|
||||
IntImportCallback( RenderModeImportCaller() ),
|
||||
IntExportCallback( RenderModeExportCaller() )
|
||||
);
|
||||
|
|
@ -2529,7 +2529,7 @@ void Camera_constructPreferences( PreferencesPage& page ){
|
|||
|
||||
page.appendCombo(
|
||||
"MSAA",
|
||||
STRING_ARRAY_RANGE( samples ),
|
||||
StringArrayRange( samples ),
|
||||
IntImportCallback( MSAAImportCaller() ),
|
||||
IntExportCallback( MSAAExportCaller() )
|
||||
);
|
||||
|
|
@ -2540,7 +2540,7 @@ void Camera_constructPreferences( PreferencesPage& page ){
|
|||
page.appendCombo(
|
||||
"Strafe Mode",
|
||||
g_camwindow_globals_private.m_strafeMode,
|
||||
STRING_ARRAY_RANGE( strafe_mode )
|
||||
StringArrayRange( strafe_mode )
|
||||
);
|
||||
|
||||
page.appendSpinner( "Field Of View", 110.0, 1.0, 175.0,
|
||||
|
|
|
|||
|
|
@ -181,7 +181,7 @@ void Clipper_constructPreferences( PreferencesPage& page ){
|
|||
const char* dowhat[] = { "Clip ", "Split", };
|
||||
page.appendRadio(
|
||||
"On DoubleClick do: ",
|
||||
STRING_ARRAY_RANGE( dowhat ),
|
||||
StringArrayRange( dowhat ),
|
||||
IntImportCaller( g_clipper_doubleclicked_split ),
|
||||
IntExportCaller( g_clipper_doubleclicked_split )
|
||||
);
|
||||
|
|
|
|||
|
|
@ -212,11 +212,11 @@ std::size_t Sys_Print( int level, const char* buf, std::size_t length ){
|
|||
GtkTextBufferOutputStream textBuffer( buffer, &iter, tag );
|
||||
if ( !globalCharacterSet().isUTF8() ) {
|
||||
BufferedTextOutputStream<GtkTextBufferOutputStream> buffered( textBuffer );
|
||||
buffered << StringRange( buf, buf + length );
|
||||
buffered << StringRange( buf, length );
|
||||
}
|
||||
else
|
||||
{
|
||||
textBuffer << StringRange( buf, buf + length );
|
||||
textBuffer << StringRange( buf, length );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -488,9 +488,9 @@ void Dialog::addCombo( GtkWidget* vbox, const char* name, StringArrayRange value
|
|||
{
|
||||
GtkWidget* combo = gtk_combo_box_text_new();
|
||||
|
||||
for ( StringArrayRange::Iterator i = values.first; i != values.last; ++i )
|
||||
for ( const char *value : values )
|
||||
{
|
||||
gtk_combo_box_text_append_text( GTK_COMBO_BOX_TEXT( combo ), *i );
|
||||
gtk_combo_box_text_append_text( GTK_COMBO_BOX_TEXT( combo ), value );
|
||||
}
|
||||
|
||||
AddIntComboData( *GTK_COMBO_BOX( combo ), importViewer, exportViewer );
|
||||
|
|
@ -575,25 +575,24 @@ void Dialog::addRadio( GtkWidget* vbox, const char* name, int& data, StringArray
|
|||
}
|
||||
|
||||
void Dialog::addRadioIcons( GtkWidget* vbox, const char* name, StringArrayRange icons, const IntImportCallback& importViewer, const IntExportCallback& exportViewer ){
|
||||
GtkWidget* table = gtk_table_new( 2, static_cast<guint>( icons.last - icons.first ), FALSE );
|
||||
GtkWidget* table = gtk_table_new( 2, icons.size(), FALSE );
|
||||
gtk_widget_show( table );
|
||||
|
||||
gtk_table_set_row_spacings( GTK_TABLE( table ), 5 );
|
||||
gtk_table_set_col_spacings( GTK_TABLE( table ), 5 );
|
||||
|
||||
GtkWidget* radio = 0;
|
||||
for ( StringArrayRange::Iterator icon = icons.first; icon != icons.last; ++icon )
|
||||
for ( size_t i = 0; i < icons.size(); ++i )
|
||||
{
|
||||
guint pos = static_cast<guint>( icon - icons.first );
|
||||
GtkImage* image = new_local_image( *icon );
|
||||
GtkImage* image = new_local_image( icons[i] );
|
||||
gtk_widget_show( GTK_WIDGET( image ) );
|
||||
gtk_table_attach( GTK_TABLE( table ), GTK_WIDGET( image ), pos, pos + 1, 0, 1,
|
||||
gtk_table_attach( GTK_TABLE( table ), GTK_WIDGET( image ), i, i + 1, 0, 1,
|
||||
(GtkAttachOptions) ( 0 ),
|
||||
(GtkAttachOptions) ( 0 ), 0, 0 );
|
||||
|
||||
radio = gtk_radio_button_new_from_widget( GTK_RADIO_BUTTON( radio ) );
|
||||
gtk_widget_show( radio );
|
||||
gtk_table_attach( GTK_TABLE( table ), radio, pos, pos + 1, 1, 2,
|
||||
gtk_table_attach( GTK_TABLE( table ), radio, i, i + 1, 1, 2,
|
||||
(GtkAttachOptions) ( 0 ),
|
||||
(GtkAttachOptions) ( 0 ), 0, 0 );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -242,10 +242,10 @@ public:
|
|||
std::size_t write( const char* data, std::size_t length ){
|
||||
CopiedString& desc = m_attribute->m_description;
|
||||
if( desc.empty() ){
|
||||
desc = StringRange( data, data + length );
|
||||
desc = StringRange( data, length );
|
||||
}
|
||||
else{ // in case of special symbols, e.g. ", &apos, <, >, &, xml writes in a few steps
|
||||
desc = StringOutputStream()( desc, StringRange( data, data + length ) );
|
||||
desc = StringOutputStream()( desc, StringRange( data, length ) );
|
||||
}
|
||||
|
||||
return m_comment.write( data, length );
|
||||
|
|
|
|||
|
|
@ -453,12 +453,6 @@ public:
|
|||
typedef MemberCaller1<AngleAttribute, const Vector3&, &AngleAttribute::apply> ApplyVecCaller;
|
||||
};
|
||||
|
||||
namespace
|
||||
{
|
||||
typedef const char* String;
|
||||
const String buttons[] = { "up", "down", "yaw" };
|
||||
}
|
||||
|
||||
class DirectionAttribute final : public EntityAttribute
|
||||
{
|
||||
CopiedString m_key;
|
||||
|
|
@ -468,11 +462,12 @@ class DirectionAttribute final : public EntityAttribute
|
|||
NonModalRadio m_nonModalRadio;
|
||||
CamAnglesButton m_butt;
|
||||
GtkHBox* m_hbox;
|
||||
static constexpr const char *const buttons[] = { "up", "down", "yaw" };
|
||||
public:
|
||||
DirectionAttribute( const char* key ) :
|
||||
m_key( key ),
|
||||
m_nonModal( ApplyCaller( *this ), UpdateCaller( *this ) ),
|
||||
m_radio( RadioHBox_new( STRING_ARRAY_RANGE( buttons ) ) ),
|
||||
m_radio( RadioHBox_new( StringArrayRange( buttons ) ) ),
|
||||
m_nonModalRadio( ApplyRadioCaller( *this ) ),
|
||||
m_butt( ApplyVecCaller( *this ) ){
|
||||
m_entry = numeric_entry_new();
|
||||
|
|
|
|||
|
|
@ -65,9 +65,8 @@ enum GridPower
|
|||
};
|
||||
|
||||
|
||||
typedef const char* GridName;
|
||||
// this must match the GridPower enumeration
|
||||
const GridName g_gridnames[] = {
|
||||
const char *const g_gridnames[] = {
|
||||
"0.125",
|
||||
"0.25",
|
||||
"0.5",
|
||||
|
|
@ -260,14 +259,14 @@ void Grid_constructPreferences( PreferencesPage& page ){
|
|||
page.appendCombo(
|
||||
"Default grid spacing",
|
||||
g_grid_default,
|
||||
ARRAY_RANGE( g_gridnames )
|
||||
StringArrayRange( g_gridnames )
|
||||
);
|
||||
{
|
||||
const char* coords[] = { "4096", "8192", "16384", "32768", "65536" };
|
||||
|
||||
page.appendCombo(
|
||||
"Max grid coordinate",
|
||||
STRING_ARRAY_RANGE( coords ),
|
||||
StringArrayRange( coords ),
|
||||
IntImportCallback( maxGridCoordPowerImportCaller() ),
|
||||
IntExportCallback( maxGridCoordPowerExportCaller() )
|
||||
);
|
||||
|
|
|
|||
|
|
@ -3500,7 +3500,7 @@ void Layout_constructPreferences( PreferencesPage& page ){
|
|||
const char* layouts[] = { "window1.png", "window2.png", "window3.png", "window4.png" };
|
||||
page.appendRadioIcons(
|
||||
"Window Layout",
|
||||
STRING_ARRAY_RANGE( layouts ),
|
||||
StringArrayRange( layouts ),
|
||||
LatchedImportCaller( g_Layout_viewStyle ),
|
||||
IntExportCaller( g_Layout_viewStyle.m_latched )
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1081,7 +1081,7 @@ static void TreeView_onRowActivated( GtkTreeView* treeview, GtkTreePath* path, G
|
|||
for( GtkTreeIter& i : iters ){
|
||||
gchar* buffer;
|
||||
gtk_tree_model_get( model, &i, 0, &buffer, -1 );
|
||||
const auto found = modelFS->m_folders.find( ModelFS( StringRange( buffer, buffer + strlen( buffer ) ) ) );
|
||||
const auto found = modelFS->m_folders.find( ModelFS( StringRange( buffer, strlen( buffer ) ) ) );
|
||||
if( found != modelFS->m_folders.end() ){ // ok to not find, while loading root
|
||||
modelFS = &( *found );
|
||||
sstream << buffer << "/";
|
||||
|
|
|
|||
|
|
@ -279,7 +279,7 @@ void CGameDialog::CreateGlobalFrame( PreferencesPage& page, bool global ){
|
|||
}
|
||||
page.appendCombo(
|
||||
"Select the game",
|
||||
StringArrayRange( &( *games.begin() ), &( *games.end() ) ),
|
||||
StringArrayRange( games ),
|
||||
global?
|
||||
IntImportCallback( MemberCaller1<CGameDialog, int, &CGameDialog::GameFileAssign>( *this ) ):
|
||||
IntImportCallback( MemberCaller1<CGameDialog, int, &CGameDialog::GameFileImport>( *this ) ),
|
||||
|
|
|
|||
|
|
@ -133,7 +133,7 @@ void printShaderLog( GLhandleARB object ){
|
|||
Array<char> log( log_length );
|
||||
glGetInfoLogARB( object, log_length, &log_length, log.data() );
|
||||
|
||||
globalErrorStream() << StringRange( log.begin(), log.begin() + log_length ) << "\n";
|
||||
globalErrorStream() << StringRange( log.begin(), log_length ) << "\n";
|
||||
}
|
||||
|
||||
void createShader( GLhandleARB program, const char* filename, GLenum type ){
|
||||
|
|
|
|||
|
|
@ -8002,7 +8002,7 @@ void SelectionSystem_constructPreferences( PreferencesPage& page ){
|
|||
const char* styles[] = { "XY plane + Z with Alt", "View plane + Forward with Alt", };
|
||||
page.appendCombo(
|
||||
"Move style in 3D",
|
||||
STRING_ARRAY_RANGE( styles ),
|
||||
StringArrayRange( styles ),
|
||||
IntImportCaller( TranslateFreeXY_Z::m_viewdependent ),
|
||||
IntExportCaller( TranslateFreeXY_Z::m_viewdependent )
|
||||
);
|
||||
|
|
|
|||
|
|
@ -720,7 +720,7 @@ void Textures_constructPreferences( PreferencesPage& page ){
|
|||
const char* percentages[] = { "100%", "50%", "25%", "12.5%", };
|
||||
page.appendRadio(
|
||||
"Texture Quality",
|
||||
STRING_ARRAY_RANGE( percentages ),
|
||||
StringArrayRange( percentages ),
|
||||
TextureMiplevelImportCaller( g_Textures_mipLevel ),
|
||||
IntExportCaller( g_Textures_mipLevel )
|
||||
);
|
||||
|
|
@ -737,7 +737,7 @@ void Textures_constructPreferences( PreferencesPage& page ){
|
|||
const char* texture_mode[] = { "Nearest", "Nearest Mipmap", "Linear", "Bilinear", "Bilinear Mipmap", "Trilinear" };
|
||||
page.appendCombo(
|
||||
"Texture Render Mode",
|
||||
STRING_ARRAY_RANGE( texture_mode ),
|
||||
StringArrayRange( texture_mode ),
|
||||
IntImportCallback( TextureModeImportCaller( g_texture_mode ) ),
|
||||
IntExportCallback( TextureModeExportCaller( g_texture_mode ) )
|
||||
);
|
||||
|
|
@ -747,14 +747,14 @@ void Textures_constructPreferences( PreferencesPage& page ){
|
|||
const char* compression_opengl[] = { "None", "OpenGL ARB" };
|
||||
const char* compression_s3tc[] = { "None", "S3TC DXT1", "S3TC DXT3", "S3TC DXT5" };
|
||||
const char* compression_opengl_s3tc[] = { "None", "OpenGL ARB", "S3TC DXT1", "S3TC DXT3", "S3TC DXT5" };
|
||||
StringArrayRange compression(
|
||||
const StringArrayRange compression(
|
||||
( g_texture_globals.m_bOpenGLCompressionSupported )
|
||||
? ( g_texture_globals.m_bS3CompressionSupported )
|
||||
? STRING_ARRAY_RANGE( compression_opengl_s3tc )
|
||||
: STRING_ARRAY_RANGE( compression_opengl )
|
||||
? StringArrayRange( compression_opengl_s3tc )
|
||||
: StringArrayRange( compression_opengl )
|
||||
: ( g_texture_globals.m_bS3CompressionSupported )
|
||||
? STRING_ARRAY_RANGE( compression_s3tc )
|
||||
: STRING_ARRAY_RANGE( compression_none )
|
||||
? StringArrayRange( compression_s3tc )
|
||||
: StringArrayRange( compression_none )
|
||||
);
|
||||
page.appendCombo(
|
||||
"Hardware Texture Compression",
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@
|
|||
#include "commands.h"
|
||||
|
||||
bool string_equal_start( const char* string, StringRange start ){
|
||||
return string_equal_n( string, start.first, start.last - start.first );
|
||||
return string_equal_n( string, start.data(), start.size() );
|
||||
}
|
||||
|
||||
typedef std::set<CopiedString> TextureGroups;
|
||||
|
|
@ -1314,7 +1314,7 @@ gboolean TextureBrowser_button_press( GtkWidget* widget, GdkEventButton* event,
|
|||
/* loads directory, containing active shader + focuses on it */
|
||||
else if ( event->type == GDK_2BUTTON_PRESS && event->button == 1 && !TextureBrowser::wads ) {
|
||||
const StringRange range( strchr( textureBrowser->shader.c_str(), '/' ) + 1, strrchr( textureBrowser->shader.c_str(), '/' ) + 1 );
|
||||
if( range.last > range.first ){
|
||||
if( !range.empty() ){
|
||||
const CopiedString dir = range;
|
||||
ScopeDisableScreenUpdates disableScreenUpdates( dir.c_str(), "Loading Textures" );
|
||||
TextureBrowser_ShowDirectory( *textureBrowser, dir.c_str() );
|
||||
|
|
@ -2670,7 +2670,7 @@ void TextureBrowser_constructPreferences( PreferencesPage& page ){
|
|||
const char* texture_scale[] = { "10%", "25%", "50%", "100%", "200%" };
|
||||
page.appendCombo(
|
||||
"Texture Thumbnail Scale",
|
||||
STRING_ARRAY_RANGE( texture_scale ),
|
||||
StringArrayRange( texture_scale ),
|
||||
IntImportCallback( TextureScaleImportCaller( GlobalTextureBrowser() ) ),
|
||||
IntExportCallback( TextureScaleExportCaller( GlobalTextureBrowser() ) )
|
||||
);
|
||||
|
|
@ -2680,7 +2680,7 @@ void TextureBrowser_constructPreferences( PreferencesPage& page ){
|
|||
page.appendEntry( "Mousewheel Increment", GlobalTextureBrowser().m_mouseWheelScrollIncrement );
|
||||
{
|
||||
const char* startup_shaders[] = { "None", TextureBrowser_getCommonShadersName() };
|
||||
page.appendCombo( "Load Shaders at Startup", reinterpret_cast<int&>( GlobalTextureBrowser().m_startupShaders ), STRING_ARRAY_RANGE( startup_shaders ) );
|
||||
page.appendCombo( "Load Shaders at Startup", reinterpret_cast<int&>( GlobalTextureBrowser().m_startupShaders ), StringArrayRange( startup_shaders ) );
|
||||
}
|
||||
{
|
||||
StringOutputStream sstream( 256 );
|
||||
|
|
|
|||
|
|
@ -395,7 +395,7 @@ inline MessageOutputStream& operator<<( MessageOutputStream& ostream, const T& t
|
|||
|
||||
static void saxCharacters( message_info_t *data, const xmlChar *ch, int len ){
|
||||
MessageOutputStream ostream( data );
|
||||
ostream << StringRange( reinterpret_cast<const char*>( ch ), reinterpret_cast<const char*>( ch + len ) );
|
||||
ostream << StringRange( reinterpret_cast<const char*>( ch ), len );
|
||||
}
|
||||
|
||||
static void saxComment( void *ctx, const xmlChar *msg ){
|
||||
|
|
|
|||
|
|
@ -2457,7 +2457,7 @@ void Orthographic_constructPreferences( PreferencesPage& page ){
|
|||
|
||||
page.appendCombo(
|
||||
"MSAA",
|
||||
STRING_ARRAY_RANGE( samples ),
|
||||
StringArrayRange( samples ),
|
||||
IntImportCallback( MSAAImportCaller() ),
|
||||
IntExportCallback( MSAAExportCaller() )
|
||||
);
|
||||
|
|
|
|||
|
|
@ -37,21 +37,6 @@
|
|||
|
||||
#include <map>
|
||||
|
||||
template<typename T>
|
||||
class Span
|
||||
{
|
||||
T * const first;
|
||||
T * const last;
|
||||
public:
|
||||
Span( T *start, int size ) : first( start ), last( start + size ){}
|
||||
T *begin() const {
|
||||
return first;
|
||||
}
|
||||
T *end() const {
|
||||
return last;
|
||||
}
|
||||
};
|
||||
|
||||
#define for_indexed(...) for_indexed_v(i, __VA_ARGS__)
|
||||
#define for_indexed_v(v, ...) if (std::size_t v = -1) for (__VA_ARGS__) if ((++v, true))
|
||||
|
||||
|
|
|
|||
|
|
@ -254,7 +254,7 @@ void AddHomeBasePath( std::vector<CopiedString>& basePaths, const char *homePath
|
|||
}
|
||||
else if ( strEqualSuffix( homePath, "/." ) ) {
|
||||
/* concatenate home dir and path */ /* remove trailing /. of homePath */
|
||||
str( StringRange( homePath, homePath + strlen( homePath ) - 1 ), homeBasePath );
|
||||
str( StringRange( homePath, strlen( homePath ) - 1 ), homeBasePath );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -884,7 +884,7 @@ static void ParseShaderFile( const char *filename ){
|
|||
|
||||
/* ignore ":q3map" suffix */
|
||||
if( striEqualSuffix( token, ":q3map" ) )
|
||||
si->shader << StringRange( token, token + strlen( token ) - strlen( ":q3map" ) );
|
||||
si->shader << StringRange( token, strlen( token ) - strlen( ":q3map" ) );
|
||||
else
|
||||
si->shader << token;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user