Initial commit

This commit is contained in:
alexpete
2021-03-05 11:26:34 -08:00
commit a10351f38d
27091 changed files with 5521199 additions and 0 deletions
@@ -0,0 +1,234 @@
#pragma once
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include <AzCore/std/iterator.h>
#include <AzCore/std/typetraits/is_pointer.h>
#include <AzCore/std/typetraits/is_reference.h>
#include <AzCore/std/typetraits/remove_reference.h>
#include <AzCore/std/utils.h>
#include <SceneAPI/SceneCore/Containers/Views/View.h>
#include <SceneAPI/SceneCore/Containers/Utilities/ProxyPointer.h>
namespace AZ
{
namespace SceneAPI
{
namespace Containers
{
namespace Views
{
// Transform allows the value of the given iterator to be converted to the assigned TransformType when dereferencing.
// A typical use case would be to change a "const shared_ptr<type>" to "const shared<const type>" for read-only
// iteration of a vector<shared_ptr<type>>.
// template argument Iterator: the base iterator which will be used as the given iterator.
// template argument TransformType: the target type the value of base iterator will be converted to.
// This requires the type stored in iterator to have conversion to this type.
// template argument Category: the iterator classification. ConvertIterator will automatically derive this
// from the given iterator and match its behavior.
// Example:
// ConvertIterator<Vector<shared_ptr<Object>>::iterator, shared_ptr<const Object>>;
//
// WARNING
// Types used for conversion that are not convertible through a reference and pointer will return their result
// by-value instead of by-reference. This may cause some unexpected behavior the user should be aware of.
template<typename Iterator>
struct ConvertIteratorArgumentHelper
{
using ArgumentType = typename AZStd::conditional<AZStd::is_pointer<
typename AZStd::iterator_traits<Iterator>::value_type>::value,
typename AZStd::iterator_traits<Iterator>::value_type,
typename AZStd::iterator_traits<Iterator>::reference>::type;
};
template<typename Iterator, typename Function>
struct ConvertIteratorFunctionHelper
{
using ArgumentType = typename ConvertIteratorArgumentHelper<Iterator>::ArgumentType;
using ReturnType = AZStd::invoke_result_t<Function, ArgumentType>;
};
template<typename Iterator, typename ReturnType>
struct ConvertIteratorTypeHelper
{
using ArgumentType = typename ConvertIteratorArgumentHelper<Iterator>::ArgumentType;
using Function = ReturnType(*)(ArgumentType);
using PointerConditionType = typename AZStd::is_reference<ReturnType>::type;
using reference = ReturnType;
using pointer = typename AZStd::conditional<AZStd::is_reference<ReturnType>::value,
typename AZStd::remove_reference<ReturnType>::type*, ProxyPointer<ReturnType> >::type;
using value_type = typename AZStd::remove_reference<ReturnType>::type;
};
template<typename Iterator, typename ReturnType, typename Category = typename AZStd::iterator_traits<Iterator>::iterator_category>
class ConvertIterator
{
};
//
// Base iterator
//
template<typename Iterator, typename ReturnType>
class ConvertIterator<Iterator, ReturnType, void>
{
public:
using value_type = typename ConvertIteratorTypeHelper<Iterator, ReturnType>::value_type;
using difference_type = typename AZStd::iterator_traits<Iterator>::difference_type;
using pointer = typename ConvertIteratorTypeHelper<Iterator, ReturnType>::pointer;
using reference = typename ConvertIteratorTypeHelper<Iterator, ReturnType>::reference;
using iterator_category = typename AZStd::iterator_traits<Iterator>::iterator_category;
using Function = typename ConvertIteratorTypeHelper<Iterator, ReturnType>::Function;
using RootIterator = ConvertIterator<Iterator, ReturnType, iterator_category>;
ConvertIterator(Iterator iterator, Function converter);
ConvertIterator(const ConvertIterator&) = default;
ConvertIterator& operator=(const ConvertIterator&) = default;
RootIterator& operator++();
RootIterator operator++(int);
const Iterator& GetBaseIterator();
protected:
Iterator m_iterator;
Function m_converter;
};
//
// input_iterator_tag
//
template<typename Iterator, typename ReturnType>
class ConvertIterator<Iterator, ReturnType, AZStd::input_iterator_tag>
: public ConvertIterator<Iterator, ReturnType, void>
{
public:
using super = ConvertIterator<Iterator, ReturnType, void>;
ConvertIterator(Iterator iterator, typename super::Function converter);
ConvertIterator(const ConvertIterator&) = default;
typename super::reference operator*() const;
typename super::pointer operator->() const;
bool operator==(const typename super::RootIterator& rhs) const;
bool operator!=(const typename super::RootIterator& rhs) const;
protected:
// Used for pointer casts that don't require an intermediate value.
typename super::pointer GetPointer(AZStd::true_type castablePointer) const;
// Used for pointer casts that require an intermediate proxy object.
typename super::pointer GetPointer(AZStd::false_type intermediateValue) const;
};
//
// forward_iterator_tag
//
template<typename Iterator, typename ReturnType>
class ConvertIterator<Iterator, ReturnType, AZStd::forward_iterator_tag>
: public ConvertIterator<Iterator, ReturnType, AZStd::input_iterator_tag>
{
public:
using super = ConvertIterator<Iterator, ReturnType, AZStd::input_iterator_tag>;
ConvertIterator(Iterator iterator, typename super::Function converter);
ConvertIterator(const ConvertIterator&) = default;
ConvertIterator();
};
//
// bidirectional_iterator_tag
//
template<typename Iterator, typename ReturnType>
class ConvertIterator<Iterator, ReturnType, AZStd::bidirectional_iterator_tag>
: public ConvertIterator<Iterator, ReturnType, AZStd::forward_iterator_tag>
{
public:
using super = ConvertIterator<Iterator, ReturnType, AZStd::forward_iterator_tag>;
ConvertIterator(Iterator iterator, typename super::Function converter);
ConvertIterator(const ConvertIterator&) = default;
ConvertIterator();
typename super::RootIterator& operator--();
typename super::RootIterator operator--(int);
};
//
// random_access_iterator_tag
//
template<typename Iterator, typename ReturnType>
class ConvertIterator<Iterator, ReturnType, AZStd::random_access_iterator_tag>
: public ConvertIterator<Iterator, ReturnType, AZStd::bidirectional_iterator_tag>
{
public:
using super = ConvertIterator<Iterator, ReturnType, AZStd::bidirectional_iterator_tag>;
ConvertIterator(Iterator iterator, typename super::Function converter);
ConvertIterator(const ConvertIterator&) = default;
ConvertIterator();
typename super::reference operator[](size_t index);
bool operator<(const typename super::RootIterator& rhs) const;
bool operator>(const typename super::RootIterator& rhs) const;
bool operator<=(const typename super::RootIterator& rhs) const;
bool operator>=(const typename super::RootIterator& rhs) const;
typename super::RootIterator operator+(size_t n) const;
typename super::RootIterator operator-(size_t n) const;
typename super::difference_type operator-(const typename super::RootIterator& rhs) const;
typename super::RootIterator& operator+=(size_t n);
typename super::RootIterator& operator-=(size_t n);
};
// contiguous_iterator_tag
template<typename Iterator, typename ReturnType>
class ConvertIterator<Iterator, ReturnType, AZStd::contiguous_iterator_tag>
: public ConvertIterator<Iterator, ReturnType, AZStd::random_access_iterator_tag>
{
public:
using super = ConvertIterator<Iterator, ReturnType, AZStd::random_access_iterator_tag>;
ConvertIterator(Iterator iterator, typename super::Function converter);
ConvertIterator(const ConvertIterator&) = default;
ConvertIterator();
};
// Utility functions
template<typename Iterator, typename Function>
ConvertIterator<Iterator, typename ConvertIteratorFunctionHelper<Iterator, Function>::ReturnType>
MakeConvertIterator(Iterator iterator, Function converter);
template<typename Iterator, typename Function>
View<ConvertIterator<Iterator, typename ConvertIteratorFunctionHelper<Iterator, Function>::ReturnType>>
MakeConvertView(Iterator begin, Iterator end, Function converter);
template<typename ViewType, typename Function>
View<ConvertIterator<typename ViewType::iterator, typename ConvertIteratorFunctionHelper<typename ViewType::iterator, Function>::ReturnType>>
MakeConvertView(ViewType& view, Function converter);
template<typename ViewType, typename Function>
View<ConvertIterator<typename ViewType::const_iterator, typename ConvertIteratorFunctionHelper<typename ViewType::const_iterator, Function>::ReturnType>>
MakeConvertView(const ViewType& view, Function converter);
} // Views
} // Containers
} // SceneAPI
} // AZ
#include <SceneAPI/SceneCore/Containers/Views/ConvertIterator.inl>
@@ -0,0 +1,277 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include <AzCore/Debug/Trace.h>
namespace AZ
{
namespace SceneAPI
{
namespace Containers
{
namespace Views
{
//
// Base iterator
//
template<typename Iterator, typename ReturnType>
ConvertIterator<Iterator, ReturnType, void>::ConvertIterator(Iterator iterator, Function converter)
: m_iterator(iterator)
, m_converter(converter)
{
}
template<typename Iterator, typename ReturnType>
auto ConvertIterator<Iterator, ReturnType, void>::operator++()->RootIterator &
{
++m_iterator;
return *static_cast<RootIterator*>(this);
}
template<typename Iterator, typename ReturnType>
auto ConvertIterator<Iterator, ReturnType, void>::operator++(int)->RootIterator
{
RootIterator result = *static_cast<RootIterator*>(this);
++m_iterator;
return result;
}
template<typename Iterator, typename ReturnType>
const Iterator& ConvertIterator<Iterator, ReturnType, void>::GetBaseIterator()
{
return m_iterator;
}
//
// input_iterator_tag
//
template<typename Iterator, typename ReturnType>
ConvertIterator<Iterator, ReturnType, AZStd::input_iterator_tag>::ConvertIterator(Iterator iterator, typename super::Function converter)
: super(iterator, converter)
{
}
template<typename Iterator, typename ReturnType>
auto ConvertIterator<Iterator, ReturnType, AZStd::input_iterator_tag>::operator*() const->typename super::reference
{
AZ_Assert(super::m_converter, "No valid conversion function set for ConvertIterator.");
return super::m_converter(*super::m_iterator);
}
template<typename Iterator, typename ReturnType>
auto ConvertIterator<Iterator, ReturnType, AZStd::input_iterator_tag>::GetPointer(
[[maybe_unused]] AZStd::true_type castablePointer) const->typename super::pointer
{
AZ_Assert(super::m_converter, "No valid conversion function set for ConvertIterator.");
return &(super::m_converter(*super::m_iterator));
}
template<typename Iterator, typename ReturnType>
auto ConvertIterator<Iterator, ReturnType, AZStd::input_iterator_tag>::GetPointer(
[[maybe_unused]] AZStd::false_type intermediateValue) const->typename super::pointer
{
AZ_Assert(super::m_converter, "No valid conversion function set for ConvertIterator.");
return typename super::pointer(super::m_converter(*super::m_iterator));
}
template<typename Iterator, typename ReturnType>
auto ConvertIterator<Iterator, ReturnType, AZStd::input_iterator_tag>::operator->() const->typename super::pointer
{
return GetPointer(typename ConvertIteratorTypeHelper<Iterator, ReturnType>::PointerConditionType());
}
template<typename Iterator, typename ReturnType>
bool ConvertIterator<Iterator, ReturnType, AZStd::input_iterator_tag>::operator==(const typename super::RootIterator& rhs) const
{
return super::m_iterator == rhs.m_iterator;
}
template<typename Iterator, typename ReturnType>
bool ConvertIterator<Iterator, ReturnType, AZStd::input_iterator_tag>::operator!=(const typename super::RootIterator& rhs) const
{
return super::m_iterator != rhs.m_iterator;
}
//
// forward_iterator_tag
//
template<typename Iterator, typename ReturnType>
ConvertIterator<Iterator, ReturnType, AZStd::forward_iterator_tag>::ConvertIterator(Iterator iterator, typename super::Function converter)
: super(iterator, converter)
{
}
template<typename Iterator, typename ReturnType>
ConvertIterator<Iterator, ReturnType, AZStd::forward_iterator_tag>::ConvertIterator()
: super(Iterator(), nullptr)
{
}
//
// bidirectional_iterator_tag
//
template<typename Iterator, typename ReturnType>
ConvertIterator<Iterator, ReturnType, AZStd::bidirectional_iterator_tag>::ConvertIterator(Iterator iterator, typename super::Function converter)
: super(iterator, converter)
{
}
template<typename Iterator, typename ReturnType>
ConvertIterator<Iterator, ReturnType, AZStd::bidirectional_iterator_tag>::ConvertIterator()
: super()
{
}
template<typename Iterator, typename ReturnType>
auto ConvertIterator<Iterator, ReturnType, AZStd::bidirectional_iterator_tag>::operator--()->typename super::RootIterator &
{
--super::m_iterator;
return *static_cast<typename super::RootIterator*>(this);
}
template<typename Iterator, typename ReturnType>
auto ConvertIterator<Iterator, ReturnType, AZStd::bidirectional_iterator_tag>::operator--(int)->typename super::RootIterator
{
typename super::RootIterator result = *static_cast<typename super::RootIterator*>(this);
--super::m_iterator;
return result;
}
//
// random_access_iterator_tag
//
template<typename Iterator, typename ReturnType>
ConvertIterator<Iterator, ReturnType, AZStd::random_access_iterator_tag>::ConvertIterator(Iterator iterator, typename super::Function converter)
: super(iterator, converter)
{
}
template<typename Iterator, typename ReturnType>
ConvertIterator<Iterator, ReturnType, AZStd::random_access_iterator_tag>::ConvertIterator()
: super()
{
}
template<typename Iterator, typename ReturnType>
auto ConvertIterator<Iterator, ReturnType, AZStd::random_access_iterator_tag>::operator[](size_t index)->typename super::reference
{
AZ_Assert(super::m_converter, "No valid conversion function set for ConvertIterator.");
return super::m_converter(super::m_iterator[index]);
}
template<typename Iterator, typename ReturnType>
bool ConvertIterator<Iterator, ReturnType, AZStd::random_access_iterator_tag>::operator<(const typename super::RootIterator& rhs) const
{
return super::m_iterator < rhs.m_iterator;
}
template<typename Iterator, typename ReturnType>
bool ConvertIterator<Iterator, ReturnType, AZStd::random_access_iterator_tag>::operator>(const typename super::RootIterator& rhs) const
{
return super::m_iterator > rhs.m_iterator;
}
template<typename Iterator, typename ReturnType>
bool ConvertIterator<Iterator, ReturnType, AZStd::random_access_iterator_tag>::operator<=(const typename super::RootIterator& rhs) const
{
return super::m_iterator <= rhs.m_iterator;
}
template<typename Iterator, typename ReturnType>
bool ConvertIterator<Iterator, ReturnType, AZStd::random_access_iterator_tag>::operator>=(const typename super::RootIterator& rhs) const
{
return super::m_iterator >= rhs.m_iterator;
}
template<typename Iterator, typename ReturnType>
auto ConvertIterator<Iterator, ReturnType, AZStd::random_access_iterator_tag>::operator+(size_t n) const->typename super::RootIterator
{
typename super::RootIterator result = *static_cast<const typename super::RootIterator*>(this);
result.m_iterator += n;
return result;
}
template<typename Iterator, typename ReturnType>
auto ConvertIterator<Iterator, ReturnType, AZStd::random_access_iterator_tag>::operator-(size_t n) const->typename super::RootIterator
{
typename super::RootIterator result = *static_cast<const typename super::RootIterator*>(this);
result.m_iterator -= n;
return result;
}
template<typename Iterator, typename ReturnType>
auto ConvertIterator<Iterator, ReturnType, AZStd::random_access_iterator_tag>::operator-(const typename super::RootIterator& rhs) const->typename super::difference_type
{
return super::m_iterator - rhs.m_iterator;
}
template<typename Iterator, typename ReturnType>
auto ConvertIterator<Iterator, ReturnType, AZStd::random_access_iterator_tag>::operator+=(size_t n)->typename super::RootIterator &
{
super::m_iterator += n;
return *static_cast<typename super::RootIterator*>(this);
}
template<typename Iterator, typename ReturnType>
auto ConvertIterator<Iterator, ReturnType, AZStd::random_access_iterator_tag>::operator-=(size_t n)->typename super::RootIterator &
{
super::m_iterator -= n;
return *static_cast<typename super::RootIterator*>(this);
}
//
// contiguous_iterator_tag
//
template<typename Iterator, typename ReturnType>
ConvertIterator<Iterator, ReturnType, AZStd::contiguous_iterator_tag>::ConvertIterator(Iterator iterator, typename super::Function converter)
: super(iterator, converter)
{
}
template<typename Iterator, typename ReturnType>
ConvertIterator<Iterator, ReturnType, AZStd::contiguous_iterator_tag>::ConvertIterator()
: super()
{
}
// Utility functions
template<typename Iterator, typename Function>
ConvertIterator<Iterator, typename ConvertIteratorFunctionHelper<Iterator, Function>::ReturnType>
MakeConvertIterator(Iterator iterator, Function converter)
{
using ReturnType = typename ConvertIteratorFunctionHelper<Iterator, Function>::ReturnType;
return ConvertIterator<Iterator, ReturnType>(iterator, converter);
}
template<typename Iterator, typename Function>
View<ConvertIterator<Iterator, typename ConvertIteratorFunctionHelper<Iterator, Function>::ReturnType>>
MakeConvertView(Iterator begin, Iterator end, Function converter)
{
using ReturnType = typename ConvertIteratorFunctionHelper<Iterator, Function>::ReturnType;
return View<ConvertIterator<Iterator, ReturnType>>(
MakeConvertIterator(begin, converter),
MakeConvertIterator(end, converter));
}
template<typename ViewType, typename Function>
View<ConvertIterator<typename ViewType::iterator, typename ConvertIteratorFunctionHelper<typename ViewType::iterator, Function>::ReturnType>>
MakeConvertView(ViewType& view, Function converter)
{
return MakeConvertView(view.begin(), view.end(), converter);
}
template<typename ViewType, typename Function>
View<ConvertIterator<typename ViewType::const_iterator, typename ConvertIteratorFunctionHelper<typename ViewType::const_iterator, Function>::ReturnType>>
MakeConvertView(const ViewType& view, Function converter)
{
return MakeConvertView(view.begin(), view.end(), converter);
}
} // Views
} // Containers
} // SceneAPI
} // AZ
@@ -0,0 +1,244 @@
#pragma once
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include <AzCore/std/utils.h>
#include <AzCore/std/iterator.h>
#include <AzCore/std/functional.h>
#include <AzCore/std/typetraits/is_base_of.h>
#include <SceneAPI/SceneCore/Containers/Views/View.h>
namespace AZ
{
namespace SceneAPI
{
namespace Containers
{
namespace Views
{
// Skips values in the iterator it wraps based on a given function's result.
// The predicate function takes the reference of the value of iterator as its
// argument and must return a boolean, where true means to accept the given
// iterator value and false if FilterIterator needs to skip to the next value.
// For complex iterators it's often easier to use decltype to derive the argument
// to the predicate function instead of fully specifying it. (See example below)
// Note:
// Because skipping happens while iterating, random access iterators will degrade
// to bidirectional iterators.
// Example:
// vector<int> list = { 10, 20, 30, 40, 50 };
// auto view = MakeFilterView(list.begin(), list.end(),
// [](int value) -> bool
// {
// return value >= 25;
// });
// for (auto it : view)
// {
// printf( "%i ", it );
// }
// result: 30 40 50
// Example:
// vector<int> list = { 10, 20, 30, 40, 50 };
// auto convertView = MakeConvertView<uint64_t>(list.begin(), list.end());
// auto filteredView = MakeFilterView(convertView,
// // Easier to read and automatically reflects any changes made in the view stack.
// [](const decltype(*convertView.begin())& object) -> bool
// {
// return value >= 25;
// });
template<typename Iterator, typename Category = typename AZStd::iterator_traits<Iterator>::iterator_category>
class FilterIterator
{
};
//
// Base iterator
//
template<typename Iterator>
class FilterIterator<Iterator, void>
{
public:
using value_type = typename AZStd::iterator_traits<Iterator>::value_type;
using difference_type = typename AZStd::iterator_traits<Iterator>::difference_type;
using pointer = typename AZStd::iterator_traits<Iterator>::pointer;
using reference = typename AZStd::iterator_traits<Iterator>::reference;
using iterator_category = typename AZStd::iterator_traits<Iterator>::iterator_category;
using RootIterator = FilterIterator<Iterator, iterator_category>;
using Predicate = AZStd::function<bool(const reference)>;
FilterIterator(Iterator iterator, Iterator end, const Predicate& predicate);
FilterIterator(const FilterIterator&) = default;
FilterIterator& operator=(const FilterIterator&) = default;
RootIterator& operator++();
RootIterator operator++(int);
const Iterator& GetBaseIterator();
protected:
// Pseudo default constructor.
// This is used because default constructing later on would trigger a predicate
// on an default constructed iterator, causing a crash when either using the
// predicate or dereferencing the iterator when trying to move forward.
explicit FilterIterator(Iterator defaultIterator);
void MoveToNext();
Iterator m_iterator;
Iterator m_end;
Predicate m_predicate;
};
//
// Input iterator
//
template<typename Iterator>
class FilterIterator<Iterator, AZStd::input_iterator_tag>
: public FilterIterator<Iterator, void>
{
public:
using super = FilterIterator<Iterator, void>;
FilterIterator(Iterator iterator, Iterator end, const typename super::Predicate& predicate);
FilterIterator(const FilterIterator& rhs) = default;
bool operator==(const typename super::RootIterator& rhs) const;
bool operator!=(const typename super::RootIterator& rhs) const;
typename super::reference operator*() const;
typename super::pointer operator->() const;
protected:
// Used when iterator is raw pointer
typename super::pointer GetPointer(AZStd::true_type) const;
// Used when iterator is an object
typename super::pointer GetPointer(AZStd::false_type) const;
// Pseudo default constructor.
explicit FilterIterator(Iterator defaultIterator);
};
//
// Forward iterator
//
template<typename Iterator>
class FilterIterator<Iterator, AZStd::forward_iterator_tag>
: public FilterIterator<Iterator, AZStd::input_iterator_tag>
{
public:
using super = FilterIterator<Iterator, AZStd::input_iterator_tag>;
FilterIterator(Iterator iterator, Iterator end, const typename super::Predicate& predicate);
FilterIterator(const FilterIterator& rhs) = default;
FilterIterator();
};
//
// Bidirectional iterator
//
template<typename Iterator>
class FilterIterator<Iterator, AZStd::bidirectional_iterator_tag>
: public FilterIterator<Iterator, AZStd::forward_iterator_tag>
{
public:
using super = FilterIterator<Iterator, AZStd::forward_iterator_tag>;
FilterIterator(Iterator iterator, Iterator end, const typename super::Predicate& predicate);
FilterIterator(Iterator iterator, Iterator begin, Iterator end, const typename super::Predicate& predicate);
FilterIterator(const FilterIterator& rhs) = default;
FilterIterator();
typename super::RootIterator& operator--();
typename super::RootIterator operator--(int);
protected:
void MoveToPrevious();
Iterator m_begin;
};
//
// Random Access iterator
// Because individual elements have to be inspected to know if they should be accepted, treat the random access iterator
// as a bidirectional iterator to force algorithms to inspect individual elements.
//
template<typename Iterator>
class FilterIterator<Iterator, AZStd::random_access_iterator_tag>
: public FilterIterator<Iterator, AZStd::bidirectional_iterator_tag>
{
public:
using super = FilterIterator<Iterator, AZStd::bidirectional_iterator_tag>;
using iterator_category = AZStd::bidirectional_iterator_tag;
FilterIterator(Iterator iterator, Iterator end, const typename super::Predicate& predicate);
FilterIterator(Iterator iterator, Iterator begin, Iterator end, const typename super::Predicate& predicate);
FilterIterator(const FilterIterator& rhs) = default;
FilterIterator();
};
//
// Contiguous Random Access iterator
// See Random Access iterator
//
template<typename Iterator>
class FilterIterator<Iterator, AZStd::contiguous_iterator_tag>
: public FilterIterator<Iterator, AZStd::bidirectional_iterator_tag>
{
public:
using super = FilterIterator<Iterator, AZStd::bidirectional_iterator_tag>;
using iterator_category = AZStd::bidirectional_iterator_tag;
FilterIterator(Iterator iterator, Iterator end, const typename super::Predicate& predicate);
FilterIterator(Iterator iterator, Iterator begin, Iterator end, const typename super::Predicate& predicate);
FilterIterator(const FilterIterator& rhs) = default;
FilterIterator();
};
//
// Utility functions
//
namespace Internal
{
template<typename Iterator>
struct FilterIteratorNeedsFullRange
{
// True if the Iterator can move backwards, which requires an end and a begin iterator, otherwise false and only
// an end iterator is needed.
static const bool value = AZStd::is_base_of<AZStd::bidirectional_iterator_tag, typename Iterator::iterator_category>::value;
};
}
template<typename Iterator>
FilterIterator<Iterator> MakeFilterIterator(Iterator current, Iterator end, const typename FilterIterator<Iterator, void>::Predicate& predicate);
template<typename Iterator, typename AZStd::enable_if<Internal::FilterIteratorNeedsFullRange<Iterator>::value>::type>
FilterIterator<Iterator> MakeFilterIterator(Iterator current, Iterator begin, Iterator end, const typename FilterIterator<Iterator, void>::Predicate& predicate);
template<typename Iterator>
View<FilterIterator<Iterator> > MakeFilterView(Iterator current, Iterator end, const typename FilterIterator<Iterator, void>::Predicate& predicate);
template<typename Iterator, typename AZStd::enable_if<Internal::FilterIteratorNeedsFullRange<Iterator>::value>::type>
View<FilterIterator<Iterator> > MakeFilterView(Iterator current, Iterator begin, Iterator end, const typename FilterIterator<Iterator>::Predicate& predicate);
template<typename ViewType>
View<FilterIterator<typename ViewType::iterator> > MakeFilterView(ViewType& view, const typename FilterIterator<typename ViewType::iterator>::Predicate& predicate);
template<typename ViewType>
const View<FilterIterator<typename ViewType::const_iterator> > MakeFilterView(const ViewType& view, const typename FilterIterator<typename ViewType::const_iterator>::Predicate& predicate);
} // Views
} // Containers
} // SceneAPI
} // AZ
#include <SceneAPI/SceneCore/Containers/Views/FilterIterator.inl>
@@ -0,0 +1,316 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include <AzCore/std/typetraits/is_pointer.h>
namespace AZ
{
namespace SceneAPI
{
namespace Containers
{
namespace Views
{
//
// Base iterator
//
template<typename Iterator>
FilterIterator<Iterator, void>::FilterIterator(Iterator iterator, Iterator end, const Predicate& predicate)
: m_iterator(iterator)
, m_end(end)
, m_predicate(predicate)
{
while (m_iterator != m_end && !m_predicate(*m_iterator))
{
AZStd::advance(m_iterator, 1);
}
}
template<typename Iterator>
FilterIterator<Iterator, void>::FilterIterator(Iterator defaultIterator)
: m_iterator(defaultIterator)
, m_end(defaultIterator)
, m_predicate()
{
}
template<typename Iterator>
auto FilterIterator<Iterator, void>::operator++()->RootIterator &
{
MoveToNext();
return *static_cast<RootIterator*>(this);
}
template<typename Iterator>
auto FilterIterator<Iterator, void>::operator++(int)->RootIterator
{
RootIterator result = *static_cast<RootIterator*>(this);
MoveToNext();
return result;
}
template<typename Iterator>
auto FilterIterator<Iterator, void>::GetBaseIterator()->const Iterator&
{
return m_iterator;
}
template<typename Iterator>
void FilterIterator<Iterator, void>::MoveToNext()
{
if (m_iterator != m_end)
{
AZStd::advance(m_iterator, 1);
}
while (m_iterator != m_end && !m_predicate(*m_iterator))
{
AZStd::advance(m_iterator, 1);
}
}
//
// Input iterator
//
template<typename Iterator>
FilterIterator<Iterator, AZStd::input_iterator_tag>::FilterIterator(Iterator iterator, Iterator end, const typename super::Predicate& predicate)
: super(iterator, end, predicate)
{
}
template<typename Iterator>
FilterIterator<Iterator, AZStd::input_iterator_tag>::FilterIterator(Iterator defaultIterator)
: super(defaultIterator)
{
}
template<typename Iterator>
bool FilterIterator<Iterator, AZStd::input_iterator_tag>::operator==(const typename super::RootIterator& rhs) const
{
return super::m_iterator == rhs.m_iterator;
}
template<typename Iterator>
bool FilterIterator<Iterator, AZStd::input_iterator_tag>::operator!=(const typename super::RootIterator& rhs) const
{
return super::m_iterator != rhs.m_iterator;
}
template<typename Iterator>
auto FilterIterator<Iterator, AZStd::input_iterator_tag>::operator*() const->typename super::reference
{
return static_cast<typename super::reference>(*super::m_iterator);
}
// Used when iterator is raw pointer
template<typename Iterator>
auto FilterIterator<Iterator, AZStd::input_iterator_tag>::GetPointer(AZStd::true_type) const->typename super::pointer
{
return super::m_iterator;
}
// Used when iterator is an object
template<typename Iterator>
auto FilterIterator<Iterator, AZStd::input_iterator_tag>::GetPointer(AZStd::false_type) const->typename super::pointer
{
return super::m_iterator.operator->();
}
template<typename Iterator>
auto FilterIterator<Iterator, AZStd::input_iterator_tag>::operator->() const->typename super::pointer
{
return GetPointer(typename AZStd::is_pointer<Iterator>::type());
}
//
// Forward iterator
//
template<typename Iterator>
FilterIterator<Iterator, AZStd::forward_iterator_tag>::FilterIterator(Iterator iterator, Iterator end, const typename super::Predicate& predicate)
: super(iterator, end, predicate)
{
}
template<typename Iterator>
FilterIterator<Iterator, AZStd::forward_iterator_tag>::FilterIterator()
: super(Iterator())
{
}
//
// Bidirectional iterator
//
template<typename Iterator>
FilterIterator<Iterator, AZStd::bidirectional_iterator_tag>::FilterIterator(Iterator iterator, Iterator end, const typename super::Predicate& predicate)
: super(iterator, end, predicate)
{
// Matches the iterator that's been moved forward to the first element that passes the predicate.
m_begin = super::m_iterator;
}
template<typename Iterator>
FilterIterator<Iterator, AZStd::bidirectional_iterator_tag>::FilterIterator(Iterator iterator, Iterator begin, Iterator end, const typename super::Predicate& predicate)
: super(iterator, end, predicate)
, m_begin(begin)
{
while (m_begin != super::m_end && !super::m_predicate(*m_begin))
{
AZStd::advance(m_begin, 1);
}
}
template<typename Iterator>
FilterIterator<Iterator, AZStd::bidirectional_iterator_tag>::FilterIterator()
: super()
{
}
template<typename Iterator>
auto FilterIterator<Iterator, AZStd::bidirectional_iterator_tag>::operator--()->typename super::RootIterator &
{
MoveToPrevious();
return *static_cast<typename super::RootIterator*>(this);
}
template<typename Iterator>
auto FilterIterator<Iterator, AZStd::bidirectional_iterator_tag>::operator--(int)->typename super::RootIterator
{
typename super::RootIterator result = *static_cast<typename super::RootIterator*>(this);
MoveToPrevious();
return result;
}
template<typename Iterator>
void FilterIterator<Iterator, AZStd::bidirectional_iterator_tag>::MoveToPrevious()
{
if (super::m_iterator != m_begin)
{
AZStd::advance(super::m_iterator, -1);
}
while (super::m_iterator != m_begin && !super::m_predicate(*super::m_iterator))
{
AZStd::advance(super::m_iterator, -1);
}
}
//
// Random Access iterator
//
template<typename Iterator>
FilterIterator<Iterator, AZStd::random_access_iterator_tag>::FilterIterator(Iterator iterator, Iterator end, const typename super::Predicate& predicate)
: super(iterator, end, predicate)
{
}
template<typename Iterator>
FilterIterator<Iterator, AZStd::random_access_iterator_tag>::FilterIterator(Iterator iterator, Iterator begin, Iterator end, const typename super::Predicate& predicate)
: super(iterator, begin, end, predicate)
{
}
template<typename Iterator>
FilterIterator<Iterator, AZStd::random_access_iterator_tag>::FilterIterator()
: super()
{
}
//
// Continuous Random Access iterator
//
template<typename Iterator>
FilterIterator<Iterator, AZStd::contiguous_iterator_tag>::FilterIterator(
Iterator iterator, Iterator end, const typename super::Predicate& predicate)
: super(iterator, end, predicate)
{
}
template<typename Iterator>
FilterIterator<Iterator, AZStd::contiguous_iterator_tag>::FilterIterator(
Iterator iterator, Iterator begin, Iterator end, const typename super::Predicate& predicate)
: super(iterator, begin, end, predicate)
{
}
template<typename Iterator>
FilterIterator<Iterator, AZStd::contiguous_iterator_tag>::FilterIterator()
: super()
{
}
//
// Utility functions
//
namespace Internal
{
template<typename Iterator>
View<FilterIterator<Iterator> > MakeFilterView(Iterator current, Iterator end,
const typename FilterIterator<Iterator>::Predicate& predicate, AZStd::false_type)
{
return View<FilterIterator<Iterator> >(
FilterIterator<Iterator>(current, end, predicate),
FilterIterator<Iterator>(end, end, predicate));
}
template<typename Iterator>
View<FilterIterator<Iterator> > MakeFilterView(Iterator current, Iterator end,
const typename FilterIterator<Iterator>::Predicate& predicate, AZStd::true_type)
{
return View<FilterIterator<Iterator> >(
FilterIterator<Iterator>(current, current, end, predicate),
FilterIterator<Iterator>(end, current, end, predicate));
}
}
template<typename Iterator>
FilterIterator<Iterator> MakeFilterIterator(Iterator current, Iterator end, const typename FilterIterator<Iterator, void>::Predicate& predicate)
{
return FilterIterator<Iterator>(current, end, predicate);
}
template<typename Iterator, typename AZStd::enable_if<Internal::FilterIteratorNeedsFullRange<Iterator>::value>::type>
FilterIterator<Iterator> MakeFilterIterator(Iterator current, Iterator begin, Iterator end, const typename FilterIterator<Iterator, void>::Predicate& predicate)
{
return FilterIterator<Iterator>(current, begin, end, predicate);
}
template<typename Iterator>
View<FilterIterator<Iterator> > MakeFilterView(Iterator current, Iterator end, const typename FilterIterator<Iterator, void>::Predicate& predicate)
{
return Internal::MakeFilterView(current, end, predicate,
typename AZStd::is_base_of<AZStd::bidirectional_iterator_tag, typename AZStd::iterator_traits<Iterator>::iterator_category>::type());
}
template<typename Iterator, typename AZStd::enable_if<Internal::FilterIteratorNeedsFullRange<Iterator>::value>::type>
View<FilterIterator<Iterator> > MakeFilterView(Iterator current, Iterator begin, Iterator end, const typename FilterIterator<Iterator>::Predicate& predicate)
{
return View<FilterIterator<Iterator> >(
FilterIterator<Iterator>(current, begin, end, predicate),
FilterIterator<Iterator>(end, begin, end, predicate));
}
template<typename ViewType>
View<FilterIterator<typename ViewType::iterator> > MakeFilterView(ViewType& view, const typename FilterIterator<typename ViewType::iterator>::Predicate& predicate)
{
return MakeFilterView(view.begin(), view.end(), predicate);
}
template<typename ViewType>
const View<FilterIterator<typename ViewType::const_iterator> > MakeFilterView(const ViewType& view, const typename FilterIterator<typename ViewType::const_iterator>::Predicate& predicate)
{
return MakeFilterView(view.begin(), view.end(), predicate);
}
} // Views
} // Containers
} // SceneAPI
} // AZ
@@ -0,0 +1,249 @@
#pragma once
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include <utility>
#include <AzCore/std/utils.h>
#include <AzCore/std/typetraits/is_same.h>
#include <AzCore/std/typetraits/is_base_of.h>
#include <AzCore/std/iterator.h>
#include <SceneAPI/SceneCore/Containers/Views/View.h>
#include <SceneAPI/SceneCore/Containers/Utilities/ProxyPointer.h>
namespace AZ
{
namespace SceneAPI
{
namespace Containers
{
namespace Views
{
// Merges two iterators together that have a pair relation.
// Both iterators must point to the same relative entry and must contain
// the same amount of remaining increments (and decrements if appropriate).
// If the categories of the given iterators differ the PairIterator
// will only support functionality shared between them. The categories
// must be implementations of or be related to the categories defined by
// the C++ standard.
// Example:
// vector<string> names;
// vector<int> values;
// auto view = MakePairView(names.begin(), names.end(), values.begin(), values.end());
// for(auto it : view)
// {
// printf("%s has value %i\n", it.first.c_str(), it.second);
// }
namespace Internal
{
template<typename FirstIterator, typename SecondIterator>
struct PairIteratorCategory
{
static const bool s_sameCategory = AZStd::is_same<
typename AZStd::iterator_traits<FirstIterator>::iterator_category,
typename AZStd::iterator_traits<SecondIterator>::iterator_category>::value;
// True if both categories are the same.
// True if FirstIterator has the lower category in the hierarchy
// False if ValueItator has the lower category or is unrelated.
static const bool s_firstIteratorCategoryIsBaseOfSecondIterator = AZStd::is_base_of<
typename AZStd::iterator_traits<FirstIterator>::iterator_category,
typename AZStd::iterator_traits<SecondIterator>::iterator_category>::value;
// True if both categories are the same.
// True if SecondIterator has the lower category in the hierarchy
// False if FirstItator has the lower category or is unrelated.
static const bool s_SecondIteratorCategoryIsBaseOfFirstIterator = AZStd::is_base_of<
typename AZStd::iterator_traits<SecondIterator>::iterator_category,
typename AZStd::iterator_traits<FirstIterator>::iterator_category>::value;
static_assert(s_sameCategory || (s_firstIteratorCategoryIsBaseOfSecondIterator != s_SecondIteratorCategoryIsBaseOfFirstIterator),
"The iterator categories for the first and second in the PairIterator are unrelated categories.");
using Category = typename AZStd::conditional<s_firstIteratorCategoryIsBaseOfSecondIterator,
typename AZStd::iterator_traits<FirstIterator>::iterator_category,
typename AZStd::iterator_traits<SecondIterator>::iterator_category>::type;
};
}
template<typename FirstIterator, typename SecondIterator,
typename Category = typename Internal::PairIteratorCategory<FirstIterator, SecondIterator>::Category>
class PairIterator
{
};
//
// Base iterator
//
template<typename FirstIterator, typename SecondIterator>
class PairIterator<FirstIterator, SecondIterator, void>
{
public:
using value_type = AZStd::pair<typename AZStd::iterator_traits<FirstIterator>::value_type, typename AZStd::iterator_traits<SecondIterator>::value_type>;
using difference_type = AZStd::ptrdiff_t;
using reference = AZStd::pair<typename AZStd::iterator_traits<FirstIterator>::reference, typename AZStd::iterator_traits<SecondIterator>::reference>;
using pointer = ProxyPointer<reference>;
using iterator_category = typename Internal::PairIteratorCategory<FirstIterator, SecondIterator>::Category;
using RootIterator = PairIterator<FirstIterator, SecondIterator, iterator_category>;
PairIterator(FirstIterator First, SecondIterator second);
PairIterator(const PairIterator&) = default;
PairIterator& operator=(const PairIterator&) = default;
RootIterator& operator++();
RootIterator operator++(int);
const FirstIterator& GetFirstIterator();
const SecondIterator& GetSecondIterator();
protected:
FirstIterator m_first;
SecondIterator m_second;
};
//
// Input iterator
//
template<typename FirstIterator, typename SecondIterator>
class PairIterator<FirstIterator, SecondIterator, AZStd::input_iterator_tag>
: public PairIterator<FirstIterator, SecondIterator, void>
{
public:
using super = PairIterator<FirstIterator, SecondIterator, void>;
PairIterator(FirstIterator first, SecondIterator second);
PairIterator(const PairIterator& rhs) = default;
bool operator==(const typename super::RootIterator& rhs) const;
bool operator!=(const typename super::RootIterator& rhs) const;
typename super::reference operator*() const;
typename super::pointer operator->() const;
};
//
// Forward iterator
//
template<typename FirstIterator, typename SecondIterator>
class PairIterator<FirstIterator, SecondIterator, AZStd::forward_iterator_tag>
: public PairIterator<FirstIterator, SecondIterator, AZStd::input_iterator_tag>
{
public:
using super = PairIterator<FirstIterator, SecondIterator, AZStd::input_iterator_tag>;
PairIterator(FirstIterator first, SecondIterator second);
PairIterator(const PairIterator& rhs) = default;
PairIterator();
};
//
// Bidirectional iterator
//
template<typename FirstIterator, typename SecondIterator>
class PairIterator<FirstIterator, SecondIterator, AZStd::bidirectional_iterator_tag>
: public PairIterator<FirstIterator, SecondIterator, AZStd::forward_iterator_tag>
{
public:
using super = PairIterator<FirstIterator, SecondIterator, AZStd::forward_iterator_tag>;
PairIterator(FirstIterator first, SecondIterator second);
PairIterator(const PairIterator& rhs) = default;
PairIterator();
typename super::RootIterator& operator--();
typename super::RootIterator operator--(int);
};
//
// Random Access iterator
//
template<typename FirstIterator, typename SecondIterator>
class PairIterator<FirstIterator, SecondIterator, AZStd::random_access_iterator_tag>
: public PairIterator<FirstIterator, SecondIterator, AZStd::bidirectional_iterator_tag>
{
public:
using super = PairIterator<FirstIterator, SecondIterator, AZStd::bidirectional_iterator_tag>;
PairIterator(FirstIterator first, SecondIterator second);
PairIterator(const PairIterator& rhs) = default;
PairIterator();
typename super::reference operator[](size_t index);
bool operator<(const typename super::RootIterator& rhs) const;
bool operator>(const typename super::RootIterator& rhs) const;
bool operator<=(const typename super::RootIterator& rhs) const;
bool operator>=(const typename super::RootIterator& rhs) const;
typename super::RootIterator operator+(size_t n) const;
typename super::RootIterator operator-(size_t n) const;
typename super::difference_type operator-(const typename super::RootIterator& rhs) const;
typename super::RootIterator& operator+=(size_t n);
typename super::RootIterator& operator-=(size_t n);
};
//
// Contiguous Random Access iterator
//
template<typename FirstIterator, typename SecondIterator>
class PairIterator<FirstIterator, SecondIterator, AZStd::contiguous_iterator_tag>
: public PairIterator<FirstIterator, SecondIterator, AZStd::random_access_iterator_tag>
{
public:
using super = PairIterator<FirstIterator, SecondIterator, AZStd::random_access_iterator_tag>;
PairIterator(FirstIterator first, SecondIterator second);
PairIterator(const PairIterator& rhs) = default;
PairIterator();
};
//
// Utility functions
//
template<typename FirstIterator, typename SecondIterator>
PairIterator<FirstIterator, SecondIterator> MakePairIterator(FirstIterator first, SecondIterator second);
template<typename FirstIterator, typename SecondIterator>
View<PairIterator<FirstIterator, SecondIterator>>
MakePairView(FirstIterator firstBegin, FirstIterator firstEnd, SecondIterator secondBegin, SecondIterator secondEnd);
template<typename FirstView, typename SecondView>
View<PairIterator<typename FirstView::iterator, typename SecondView::iterator>>
MakePairView(FirstView& firstView, SecondView& secondView);
template<typename FirstView, typename SecondView>
View<PairIterator<typename FirstView::const_iterator, typename SecondView::iterator>>
MakePairView(const FirstView& firstView, SecondView& secondView);
template<typename FirstView, typename SecondView>
View<PairIterator<typename FirstView::iterator, typename SecondView::const_iterator>>
MakePairView(FirstView& firstView, const SecondView& secondView);
template<typename FirstView, typename SecondView>
View<PairIterator<typename FirstView::const_iterator, typename SecondView::const_iterator>>
MakePairView(const FirstView& firstView, const SecondView& secondView);
} // Views
} // Containers
} // SceneAPI
} // AZ
namespace AZStd
{
// iterator swap
template<typename First, typename Second>
void iter_swap(AZ::SceneAPI::Containers::Views::PairIterator<First, Second> lhs, AZ::SceneAPI::Containers::Views::PairIterator<First, Second> rhs);
}
#include <SceneAPI/SceneCore/Containers/Views/PairIterator.inl>
@@ -0,0 +1,318 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include <AzCore/Debug/Trace.h>
#include <AzCore/std/typetraits/remove_pointer.h>
#include <AzCore/std/typetraits/remove_reference.h>
namespace AZ
{
namespace SceneAPI
{
namespace Containers
{
namespace Views
{
//
// Base iterator
//
template<typename FirstIterator, typename SecondIterator>
PairIterator<FirstIterator, SecondIterator, void>::PairIterator(FirstIterator first, SecondIterator second)
: m_first(first)
, m_second(second)
{
}
template<typename FirstIterator, typename SecondIterator>
auto PairIterator<FirstIterator, SecondIterator, void>::operator++()->RootIterator &
{
++m_first;
++m_second;
return *static_cast<RootIterator*>(this);
}
template<typename FirstIterator, typename SecondIterator>
auto PairIterator<FirstIterator, SecondIterator, void>::operator++(int)->RootIterator
{
RootIterator result = *static_cast<RootIterator*>(this);
++m_first;
++m_second;
return result;
}
template<typename FirstIterator, typename SecondIterator>
auto PairIterator<FirstIterator, SecondIterator, void>::GetFirstIterator()->const FirstIterator&
{
return m_first;
}
template<typename FirstIterator, typename SecondIterator>
auto PairIterator<FirstIterator, SecondIterator, void>::GetSecondIterator()->const SecondIterator&
{
return m_second;
}
//
// Input iterator
//
template<typename FirstIterator, typename SecondIterator>
PairIterator<FirstIterator, SecondIterator, AZStd::input_iterator_tag>::PairIterator(FirstIterator first, SecondIterator second)
: super(first, second)
{
}
template<typename FirstIterator, typename SecondIterator>
bool PairIterator<FirstIterator, SecondIterator, AZStd::input_iterator_tag>::operator==(const typename super::RootIterator& rhs) const
{
return super::m_first == rhs.m_first && super::m_second == rhs.m_second;
}
template<typename FirstIterator, typename SecondIterator>
bool PairIterator<FirstIterator, SecondIterator, AZStd::input_iterator_tag>::operator!=(const typename super::RootIterator& rhs) const
{
return super::m_first != rhs.m_first || super::m_second != rhs.m_second;
}
template<typename FirstIterator, typename SecondIterator>
auto PairIterator<FirstIterator, SecondIterator, AZStd::input_iterator_tag>::operator*() const ->typename super::reference
{
return typename super::reference(*super::m_first, *super::m_second);
}
template<typename FirstIterator, typename SecondIterator>
auto PairIterator<FirstIterator, SecondIterator, AZStd::input_iterator_tag>::operator->() const ->typename super::pointer
{
return typename super::pointer(operator*());
}
//
// Forward iterator
//
template<typename FirstIterator, typename SecondIterator>
PairIterator<FirstIterator, SecondIterator, AZStd::forward_iterator_tag>::PairIterator(FirstIterator first, SecondIterator second)
: super(first, second)
{
}
template<typename FirstIterator, typename SecondIterator>
PairIterator<FirstIterator, SecondIterator, AZStd::forward_iterator_tag>::PairIterator()
: super(FirstIterator(), SecondIterator())
{
}
//
// Bidirectional iterator
//
template<typename FirstIterator, typename SecondIterator>
PairIterator<FirstIterator, SecondIterator, AZStd::bidirectional_iterator_tag>::PairIterator(FirstIterator first, SecondIterator second)
: super(first, second)
{
}
template<typename FirstIterator, typename SecondIterator>
PairIterator<FirstIterator, SecondIterator, AZStd::bidirectional_iterator_tag>::PairIterator()
: super()
{
}
template<typename FirstIterator, typename SecondIterator>
auto PairIterator<FirstIterator, SecondIterator, AZStd::bidirectional_iterator_tag>::operator--()->typename super::RootIterator &
{
--super::m_first;
--super::m_second;
return *static_cast<typename super::RootIterator*>(this);
}
template<typename FirstIterator, typename SecondIterator>
auto PairIterator<FirstIterator, SecondIterator, AZStd::bidirectional_iterator_tag>::operator--(int)->typename super::RootIterator
{
typename super::RootIterator result = *static_cast<typename super::RootIterator*>(this);
--super::m_first;
--super::m_second;
return result;
}
//
// Random Access iterator
//
template<typename FirstIterator, typename SecondIterator>
PairIterator<FirstIterator, SecondIterator, AZStd::random_access_iterator_tag>::PairIterator(FirstIterator first, SecondIterator second)
: super(first, second)
{
}
template<typename FirstIterator, typename SecondIterator>
PairIterator<FirstIterator, SecondIterator, AZStd::random_access_iterator_tag>::PairIterator()
: super()
{
}
template<typename FirstIterator, typename SecondIterator>
auto PairIterator<FirstIterator, SecondIterator, AZStd::random_access_iterator_tag>::operator[](size_t index)->typename super::reference
{
return typename super::reference(super::m_first[index], super::m_second[index]);
}
template<typename FirstIterator, typename SecondIterator>
bool IsSmaller(const FirstIterator& lhsFirst, const FirstIterator& lhsSecond, const SecondIterator& rhsFirst, const SecondIterator& rhsSecond)
{
return (lhsFirst < rhsFirst || (!(rhsFirst < lhsFirst) && lhsSecond < rhsSecond));
}
template<typename FirstIterator, typename SecondIterator>
bool PairIterator<FirstIterator, SecondIterator, AZStd::random_access_iterator_tag>::operator<(const typename super::RootIterator& rhs) const
{
return IsSmaller(super::m_first, super::m_second, rhs.m_first, rhs.m_second);
}
template<typename FirstIterator, typename SecondIterator>
bool PairIterator<FirstIterator, SecondIterator, AZStd::random_access_iterator_tag>::operator>(const typename super::RootIterator& rhs) const
{
return IsSmaller(rhs.m_first, rhs.m_second, super::m_first, super::m_second);
}
template<typename FirstIterator, typename SecondIterator>
bool PairIterator<FirstIterator, SecondIterator, AZStd::random_access_iterator_tag>::operator<=(const typename super::RootIterator& rhs) const
{
return !IsSmaller(rhs.m_first, rhs.m_second, super::m_first, super::m_second);
}
template<typename FirstIterator, typename SecondIterator>
bool PairIterator<FirstIterator, SecondIterator, AZStd::random_access_iterator_tag>::operator>=(const typename super::RootIterator& rhs) const
{
return !IsSmaller(super::m_first, super::m_second, rhs.m_first, rhs.m_second);
}
template<typename FirstIterator, typename SecondIterator>
auto PairIterator<FirstIterator, SecondIterator, AZStd::random_access_iterator_tag>::operator+(size_t n) const->typename super::RootIterator
{
typename super::RootIterator result = *static_cast<const typename super::RootIterator*>(this);
result.m_first += n;
result.m_second += n;
return result;
}
template<typename FirstIterator, typename SecondIterator>
auto PairIterator<FirstIterator, SecondIterator, AZStd::random_access_iterator_tag>::operator-(size_t n) const->typename super::RootIterator
{
typename super::RootIterator result = *static_cast<const typename super::RootIterator*>(this);
result.m_first -= n;
result.m_second -= n;
return result;
}
template<typename FirstIterator, typename SecondIterator>
auto PairIterator<FirstIterator, SecondIterator, AZStd::random_access_iterator_tag>::operator-(const typename super::RootIterator& rhs) const->typename super::difference_type
{
typename super::difference_type result = super::m_first - rhs.m_first;
AZ_Assert((super::m_second - rhs.m_second) == result, "First and second in PairIterator have gone out of lockstep.");
return result;
}
template<typename FirstIterator, typename SecondIterator>
auto PairIterator<FirstIterator, SecondIterator, AZStd::random_access_iterator_tag>::operator+=(size_t n)->typename super::RootIterator &
{
super::m_first += n;
super::m_second += n;
return *static_cast<typename super::RootIterator*>(this);
}
template<typename FirstIterator, typename SecondIterator>
auto PairIterator<FirstIterator, SecondIterator, AZStd::random_access_iterator_tag>::operator-=(size_t n)->typename super::RootIterator &
{
super::m_first -= n;
super::m_second -= n;
return *static_cast<typename super::RootIterator*>(this);
}
//
// Contiguous Random Access iterator
//
template<typename FirstIterator, typename SecondIterator>
PairIterator<FirstIterator, SecondIterator, AZStd::contiguous_iterator_tag>::PairIterator(
FirstIterator first, SecondIterator second)
: super(first, second)
{
}
template<typename FirstIterator, typename SecondIterator>
PairIterator<FirstIterator, SecondIterator, AZStd::contiguous_iterator_tag>::PairIterator()
: super()
{
}
//
// Utility functions
//
template<typename FirstIterator, typename SecondIterator>
PairIterator<FirstIterator, SecondIterator> MakePairIterator(FirstIterator first, SecondIterator second)
{
return PairIterator<FirstIterator, SecondIterator>(first, second);
}
template<typename FirstIterator, typename SecondIterator>
View<PairIterator<FirstIterator, SecondIterator>>
MakePairView(FirstIterator firstBegin, FirstIterator firstEnd, SecondIterator secondBegin, SecondIterator secondEnd)
{
return View<PairIterator<FirstIterator, SecondIterator>>(
PairIterator<FirstIterator, SecondIterator>(firstBegin, secondBegin),
PairIterator<FirstIterator, SecondIterator>(firstEnd, secondEnd));
}
template<typename FirstView, typename SecondView>
View<PairIterator<typename FirstView::iterator, typename SecondView::iterator>>
MakePairView(FirstView& firstView, SecondView& secondView)
{
return MakePairView(firstView.begin(), firstView.end(), secondView.begin(), secondView.end());
}
template<typename FirstView, typename SecondView>
View<PairIterator<typename FirstView::const_iterator, typename SecondView::iterator>>
MakePairView(const FirstView& firstView, SecondView& secondView)
{
return MakePairView(firstView.begin(), firstView.end(), secondView.begin(), secondView.end());
}
template<typename FirstView, typename SecondView>
View<PairIterator<typename FirstView::iterator, typename SecondView::const_iterator>>
MakePairView(FirstView& firstView, const SecondView& secondView)
{
return MakePairView(firstView.begin(), firstView.end(), secondView.begin(), secondView.end());
}
template<typename FirstView, typename SecondView>
View<PairIterator<typename FirstView::const_iterator, typename SecondView::const_iterator>>
MakePairView(const FirstView& firstView, const SecondView& secondView)
{
return MakePairView(firstView.begin(), firstView.end(), secondView.begin(), secondView.end());
}
} // Views
} // Containers
} // SceneAPI
} // AZ
namespace AZStd
{
// iterator swap
template<typename First, typename Second>
void iter_swap(AZ::SceneAPI::Containers::Views::PairIterator<First, Second> lhs, AZ::SceneAPI::Containers::Views::PairIterator<First, Second> rhs)
{
typename remove_pointer<typename remove_reference<First>::type>::type tmpFirst = (*lhs).first;
typename remove_pointer<typename remove_reference<Second>::type>::type tmpSecond = (*lhs).second;
(*lhs).first = (*rhs).first;
(*lhs).second = (*rhs).second;
(*rhs).first = tmpFirst;
(*rhs).second = tmpSecond;
}
}
@@ -0,0 +1,156 @@
#pragma once
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include <iterator>
#include <type_traits>
#include <AzCore/std/iterator.h>
#include <AzCore/std/typetraits/is_base_of.h>
#include <SceneAPI/SceneCore/Containers/Views/View.h>
#include <SceneAPI/SceneCore/Containers/SceneGraph.h>
namespace AZ
{
namespace SceneAPI
{
namespace Containers
{
namespace Views
{
struct FilterAcceptanceTag {};
// Filter tag to only show regular nodes.
struct AcceptNodesOnly : public FilterAcceptanceTag {};
// Filter tag to only show end points.
struct AcceptEndPointsOnly : public FilterAcceptanceTag {};
// Filter tag to show all nodes.
struct AcceptAll : public FilterAcceptanceTag {};
// Iterator to traverse a SceneGraph from a given node by listing all the direct children. The given node will not be included in the
// iteration. By default all children are listed, but optionally only regular nodes or only end points can be returned by
// specifying the appropriate tag (see example below).
// Example:
// auto view = MakeSceneGraphChildView(graph, graph.ConvertToHierarchyIterator(nodeIndex), graph.GetNameStorage().begin(), true);
// for (auto& it : view)
// {
// printf("Node: %s\n", it.c_str());
// }
//
// Example:
// auto view = MakeSceneGraphChildView<AcceptEndPointsOnly>(graph, nodeIndex, graph.GetNameStorage().begin(), true);
// for (auto& it : view)
// {
// printf("End point: %s\n", it.c_str());
// }
template<typename Iterator, typename Filter = AcceptAll>
class SceneGraphChildIterator
{
static_assert(AZStd::is_base_of<FilterAcceptanceTag, Filter>::value,
"Filter for SceneGraphChildIterator is not a valid tag. Use AcceptNodesOnly, AcceptEndPointsOnly, AcceptAll or leave blank.");
static_assert(AZStd::is_base_of<AZStd::bidirectional_iterator_tag, typename AZStd::iterator_traits<Iterator>::iterator_category>::value,
"SceneGraphChildIterator needs at least a bidirectional iterator for its data iterator.");
public:
using value_type = typename AZStd::iterator_traits<Iterator>::value_type;
using difference_type = AZStd::ptrdiff_t;
using pointer = typename AZStd::iterator_traits<Iterator>::pointer;
using reference = typename AZStd::iterator_traits<Iterator>::reference;
using iterator_category = AZStd::forward_iterator_tag;
// Creates an iterator at a specified node in the hierarchy.
// graph: SceneGraph that will traversed.
// graphIterator: The node to start traversing from.
// iterator: The data iterator to be dereferenced from.
// rootIterator: If true the data iterator will be the first iterator from the data and
// this iterator will be moved forward to match the graph iterator. If false
// the graph iterator and the data iterator should be pointing to the same relative
// element.
SceneGraphChildIterator(const SceneGraph& graph, SceneGraph::HierarchyStorageConstIterator graphIterator, Iterator iterator, bool rootIterator);
SceneGraphChildIterator(const SceneGraphChildIterator&) = default;
SceneGraphChildIterator();
SceneGraphChildIterator& operator=(const SceneGraphChildIterator&) = default;
SceneGraphChildIterator& operator++();
SceneGraphChildIterator operator++(int);
bool operator==(const SceneGraphChildIterator& rhs) const;
bool operator!=(const SceneGraphChildIterator& rhs) const;
reference operator*() const;
pointer operator->() const;
SceneGraph::HierarchyStorageConstIterator GetHierarchyIterator() const;
private:
// For iterators that are raw pointers.
pointer GetPointer(AZStd::true_type) const;
// For all other types of iterator.
pointer GetPointer(AZStd::false_type) const;
void MoveToNext();
bool ShouldAcceptNode(AcceptNodesOnly) const;
bool ShouldAcceptNode(AcceptEndPointsOnly) const;
bool ShouldAcceptNode(AcceptAll) const;
const SceneGraph* m_graph;
Iterator m_iterator;
int32_t m_index;
};
//
// Iterator construction
//
template<typename Filter, typename Iterator>
SceneGraphChildIterator<Iterator, Filter> MakeSceneGraphChildIterator(
const SceneGraph& graph, SceneGraph::HierarchyStorageConstIterator graphIterator, Iterator iterator, bool rootIterator);
template<typename Filter, typename Iterator>
SceneGraphChildIterator<Iterator, Filter> MakeSceneGraphChildIterator(
const SceneGraph& graph, SceneGraph::NodeIndex node, Iterator iterator, bool rootIterator);
template<typename Iterator>
SceneGraphChildIterator<Iterator> MakeSceneGraphChildIterator(
const SceneGraph& graph, SceneGraph::HierarchyStorageConstIterator graphIterator, Iterator iterator, bool rootIterator);
template<typename Iterator>
SceneGraphChildIterator<Iterator> MakeSceneGraphChildIterator(
const SceneGraph& graph, SceneGraph::NodeIndex node, Iterator iterator, bool rootIterator);
//
// View construction
//
template<typename Filter, typename Iterator>
View<SceneGraphChildIterator<Iterator, Filter> > MakeSceneGraphChildView(
const SceneGraph& graph, SceneGraph::HierarchyStorageConstIterator graphIterator, Iterator iterator, bool rootIterator);
template<typename Filter, typename Iterator>
View<SceneGraphChildIterator<Iterator, Filter> > MakeSceneGraphChildView(
const SceneGraph& graph, SceneGraph::NodeIndex node, Iterator iterator, bool rootIterator);
template<typename Iterator>
View<SceneGraphChildIterator<Iterator> > MakeSceneGraphChildView(
const SceneGraph& graph, SceneGraph::HierarchyStorageConstIterator graphIterator, Iterator iterator, bool rootIterator);
template<typename Iterator>
View<SceneGraphChildIterator<Iterator> > MakeSceneGraphChildView(
const SceneGraph& graph, SceneGraph::NodeIndex node, Iterator iterator, bool rootIterator);
} // Views
} // Containers
} // SceneAPI
} // AZ
#include <SceneAPI/SceneCore/Containers/Views/SceneGraphChildIterator.inl>
@@ -0,0 +1,222 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
namespace AZ
{
namespace SceneAPI
{
namespace Containers
{
namespace Views
{
template<typename Iterator, typename Filter>
SceneGraphChildIterator<Iterator, Filter>::SceneGraphChildIterator(
const SceneGraph& graph, SceneGraph::HierarchyStorageConstIterator graphIterator, Iterator iterator, bool rootIterator)
: m_index(-1)
, m_graph(nullptr)
{
if (graph.GetHierarchyStorage().end() != graphIterator)
{
if (graphIterator->HasChild())
{
m_graph = &graph;
m_index = graphIterator->m_childIndex;
s32 delta = rootIterator ? static_cast<s32>(m_index) : graph.ConvertToNodeIndex(graphIterator).Distance(graphIterator->GetChildIndex());
m_iterator = AZStd::next(iterator, delta);
if (!ShouldAcceptNode(Filter()))
{
MoveToNext();
}
}
}
}
template<typename Iterator, typename Filter>
SceneGraphChildIterator<Iterator, Filter>::SceneGraphChildIterator()
: m_graph(nullptr)
, m_index(-1)
{
}
template<typename Iterator, typename Filter>
auto SceneGraphChildIterator<Iterator, Filter>::operator++()->SceneGraphChildIterator &
{
MoveToNext();
return *this;
}
template<typename Iterator, typename Filter>
auto SceneGraphChildIterator<Iterator, Filter>::operator++(int)->SceneGraphChildIterator
{
SceneGraphChildIterator result = *this;
MoveToNext();
return result;
}
template<typename Iterator, typename Filter>
bool SceneGraphChildIterator<Iterator, Filter>::operator==(const SceneGraphChildIterator& rhs) const
{
return m_graph == rhs.m_graph && m_index == rhs.m_index;
}
template<typename Iterator, typename Filter>
bool SceneGraphChildIterator<Iterator, Filter>::operator!=(const SceneGraphChildIterator& rhs) const
{
return m_graph != rhs.m_graph || m_index != rhs.m_index;
}
template<typename Iterator, typename Filter>
auto SceneGraphChildIterator<Iterator, Filter>::operator*() const->reference
{
return *m_iterator;
}
template<typename Iterator, typename Filter>
auto SceneGraphChildIterator<Iterator, Filter>::GetPointer(AZStd::true_type) const->pointer
{
return m_iterator;
}
template<typename Iterator, typename Filter>
auto SceneGraphChildIterator<Iterator, Filter>::GetPointer(AZStd::false_type) const->pointer
{
return m_iterator.operator->();
}
template<typename Iterator, typename Filter>
auto SceneGraphChildIterator<Iterator, Filter>::operator->() const->pointer
{
return GetPointer(typename AZStd::is_pointer<Iterator>::type());
}
template<typename Iterator, typename Filter>
SceneGraph::HierarchyStorageConstIterator SceneGraphChildIterator<Iterator, Filter>::GetHierarchyIterator() const
{
if (m_index >= 0)
{
return AZStd::next(m_graph->GetHierarchyStorage().begin(), m_index);
}
else
{
return SceneGraph::HierarchyStorageConstIterator();
}
}
template<typename Iterator, typename Filter>
void SceneGraphChildIterator<Iterator, Filter>::MoveToNext()
{
do
{
SceneGraph::NodeHeader header = m_graph->GetHierarchyStorage().begin()[m_index];
if (header.HasSibling())
{
AZStd::advance(m_iterator, header.m_siblingIndex - m_index);
m_index = header.m_siblingIndex;
}
else
{
m_index = -1;
m_graph = nullptr;
return;
}
} while (!ShouldAcceptNode(Filter()));
}
template<typename Iterator, typename Filter>
bool SceneGraphChildIterator<Iterator, Filter>::ShouldAcceptNode(AcceptNodesOnly) const
{
SceneGraph::NodeHeader header = m_graph->GetHierarchyStorage().begin()[m_index];
return !header.IsEndPoint();
}
template<typename Iterator, typename Filter>
bool SceneGraphChildIterator<Iterator, Filter>::ShouldAcceptNode(AcceptEndPointsOnly) const
{
SceneGraph::NodeHeader header = m_graph->GetHierarchyStorage().begin()[m_index];
return header.IsEndPoint();
}
template<typename Iterator, typename Filter>
bool SceneGraphChildIterator<Iterator, Filter>::ShouldAcceptNode(AcceptAll) const
{
return true;
}
template<typename Filter, typename Iterator>
SceneGraphChildIterator<Iterator, Filter> MakeSceneGraphChildIterator(
const SceneGraph& graph, SceneGraph::HierarchyStorageConstIterator graphIterator, Iterator iterator, bool rootIterator)
{
return SceneGraphChildIterator<Iterator, Filter>(graph, graphIterator, iterator, rootIterator);
}
template<typename Filter, typename Iterator>
SceneGraphChildIterator<Iterator, Filter> MakeSceneGraphChildIterator(
const SceneGraph& graph, SceneGraph::NodeIndex node, Iterator iterator, bool rootIterator)
{
return SceneGraphChildIterator<Iterator, Filter>(graph, graph.ConvertToHierarchyIterator(node), iterator, rootIterator);
}
template<typename Iterator>
SceneGraphChildIterator<Iterator> MakeSceneGraphChildIterator(
const SceneGraph& graph, SceneGraph::HierarchyStorageConstIterator graphIterator, Iterator iterator, bool rootIterator)
{
return SceneGraphChildIterator<Iterator>(graph, graphIterator, iterator, rootIterator);
}
template<typename Iterator>
SceneGraphChildIterator<Iterator> MakeSceneGraphChildIterator(
const SceneGraph& graph, SceneGraph::NodeIndex node, Iterator iterator, bool rootIterator)
{
return SceneGraphChildIterator<Iterator>(graph, graph.ConvertToHierarchyIterator(node), iterator, rootIterator);
}
template<typename Filter, typename Iterator>
View<SceneGraphChildIterator<Iterator, Filter> > MakeSceneGraphChildView(
const SceneGraph& graph, SceneGraph::HierarchyStorageConstIterator graphIterator, Iterator iterator, bool rootIterator)
{
return View<SceneGraphChildIterator<Iterator, Filter> >(
SceneGraphChildIterator<Iterator, Filter>(graph, graphIterator, iterator, rootIterator),
SceneGraphChildIterator<Iterator, Filter>());
}
template<typename Filter, typename Iterator>
View<SceneGraphChildIterator<Iterator, Filter> > MakeSceneGraphChildView(
const SceneGraph& graph, SceneGraph::NodeIndex node, Iterator iterator, bool rootIterator)
{
return View<SceneGraphChildIterator<Iterator, Filter> >(
SceneGraphChildIterator<Iterator, Filter>(graph, graph.ConvertToHierarchyIterator(node), iterator, rootIterator),
SceneGraphChildIterator<Iterator, Filter>());
}
template<typename Iterator>
View<SceneGraphChildIterator<Iterator> > MakeSceneGraphChildView(
const SceneGraph& graph, SceneGraph::HierarchyStorageConstIterator graphIterator, Iterator iterator, bool rootIterator)
{
return View<SceneGraphChildIterator<Iterator> >(
SceneGraphChildIterator<Iterator>(graph, graphIterator, iterator, rootIterator),
SceneGraphChildIterator<Iterator>());
}
template<typename Iterator>
View<SceneGraphChildIterator<Iterator> > MakeSceneGraphChildView(
const SceneGraph& graph, SceneGraph::NodeIndex node, Iterator iterator, bool rootIterator)
{
return View<SceneGraphChildIterator<Iterator> >(
SceneGraphChildIterator<Iterator>(graph, graph.ConvertToHierarchyIterator(node), iterator, rootIterator),
SceneGraphChildIterator<Iterator>());
}
} // Views
} // Containers
} // SceneAPI
} // AZ
@@ -0,0 +1,135 @@
#pragma once
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include <deque>
#include <iterator>
#include <type_traits>
#include <AzCore/std/iterator.h>
#include <SceneAPI/SceneCore/Containers/SceneGraph.h>
#include <SceneAPI/SceneCore/Containers/Views/View.h>
namespace AZ
{
namespace SceneAPI
{
namespace Containers
{
namespace Views
{
// Tag for depth-first traversal
struct DepthFirst {};
// Tag for breadth-first traversal
struct BreadthFirst {};
// Iterator to traverse a SceneGraph downwards from the root or a given hierarchy iterator either
// depth-first or breadth-first. If a hierarchy iterator is specified it will be the first
// entry returned, otherwise the root.
// Example:
// auto view = MakeSceneGraphDownwardsView<DepthFirst>(graph, graph.GetNameStorage().begin());
// for (auto it : view)
// {
// printf("Node: %s\n", it.c_str());
// }
// Example:
// SceneGraph::NodeIndex search = graph.Find("A.C");
// auto view = MakeSceneGraphDownwardsView<BreadthFirst>(graph, graph.ConvertToHierarchyIterator(search), graph.GetNameStorage().begin(), true);
// for (auto it : view)
// {
// printf("Node: %s\n", it.c_str());
// }
template<typename Iterator, typename Traversal>
class SceneGraphDownwardsIterator
{
static_assert(std::is_base_of<AZStd::bidirectional_iterator_tag, typename AZStd::iterator_traits<Iterator>::iterator_category>::value,
"SceneGraphDownwardsIterator needs at least a bidrectional iterator for its data iterator.");
public:
using value_type = typename AZStd::iterator_traits<Iterator>::value_type;
using difference_type = std::ptrdiff_t;
using pointer = typename AZStd::iterator_traits<Iterator>::pointer;
using reference = typename AZStd::iterator_traits<Iterator>::reference;
using iterator_category = AZStd::forward_iterator_tag;
// Creates an iterator at the root node in the hierarchy.
SceneGraphDownwardsIterator(const SceneGraph& graph, Iterator iterator);
// Creates an iterator at a specified node in the hierarchy.
// graph: SceneGraph that will traversed.
// graphIterator: The node to start traversing from.
// iterator: The data iterator to be dereferenced from.
// rootIterator: If true the data iterator will be the first iterator from the data and
// this iterator will be moved forward to match the graph iterator. If false
// the graph iterator and the data iterator should be pointing to the same relative
// element.
SceneGraphDownwardsIterator(const SceneGraph& graph, SceneGraph::HierarchyStorageConstIterator graphIterator, Iterator iterator, bool rootIterator);
SceneGraphDownwardsIterator(const SceneGraphDownwardsIterator&) = default;
SceneGraphDownwardsIterator();
SceneGraphDownwardsIterator& operator=(const SceneGraphDownwardsIterator&) = default;
SceneGraphDownwardsIterator& operator++();
SceneGraphDownwardsIterator operator++(int);
bool operator==(const SceneGraphDownwardsIterator& rhs) const;
bool operator!=(const SceneGraphDownwardsIterator& rhs) const;
reference operator*() const;
pointer operator->() const;
SceneGraph::HierarchyStorageConstIterator GetHierarchyIterator() const;
// Stops the iterator from descending into the children of the current node. Pending nodes and their children will be processed as normal.
// This call can be made multiple times for different nodes.
void IgnoreNodeDescendants();
private:
// For iterators that are raw pointers.
pointer GetPointer(AZStd::true_type) const;
// For all other types of iterator.
pointer GetPointer(AZStd::false_type) const;
void MoveToNext(DepthFirst);
void MoveToNext(BreadthFirst);
void JumpTo(int32_t index);
std::deque<int32_t> m_pending;
const SceneGraph* m_graph;
Iterator m_iterator;
int32_t m_index : 30;
int32_t m_firstNode : 1;
int32_t m_ignoreDescendants : 1;
};
template<typename Traversal, typename Iterator>
SceneGraphDownwardsIterator<Iterator, Traversal> MakeSceneGraphDownwardsIterator(const SceneGraph& graph, Iterator iterator);
template<typename Traversal, typename Iterator>
SceneGraphDownwardsIterator<Iterator, Traversal> MakeSceneGraphDownwardsIterator(
const SceneGraph& graph, SceneGraph::HierarchyStorageConstIterator graphIterator, Iterator iterator, bool rootIterator);
template<typename Traversal, typename Iterator>
SceneGraphDownwardsIterator<Iterator, Traversal> MakeSceneGraphDownwardsIterator(
const SceneGraph& graph, SceneGraph::NodeIndex node, Iterator iterator, bool rootIterator);
template<typename Traversal, typename Iterator>
View<SceneGraphDownwardsIterator<Iterator, Traversal> > MakeSceneGraphDownwardsView(const SceneGraph& graph, Iterator iterator);
template<typename Traversal, typename Iterator>
View<SceneGraphDownwardsIterator<Iterator, Traversal> > MakeSceneGraphDownwardsView(
const SceneGraph& graph, SceneGraph::HierarchyStorageConstIterator graphIterator, Iterator iterator, bool rootIterator);
template<typename Traversal, typename Iterator>
View<SceneGraphDownwardsIterator<Iterator, Traversal> > MakeSceneGraphDownwardsView(
const SceneGraph& graph, SceneGraph::NodeIndex node, Iterator iterator, bool rootIterator);
} // Views
} // Containers
} // SceneAPI
} // AZ
#include <SceneAPI/SceneCore/Containers/Views/SceneGraphDownwardsIterator.inl>
@@ -0,0 +1,242 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include <AzCore/std/typetraits/is_pointer.h>
namespace AZ
{
namespace SceneAPI
{
namespace Containers
{
namespace Views
{
template<typename Iterator, typename Traversal>
SceneGraphDownwardsIterator<Iterator, Traversal>::SceneGraphDownwardsIterator(const SceneGraph& graph, Iterator iterator)
: m_graph(&graph)
, m_iterator(iterator)
, m_index(0)
, m_ignoreDescendants(false)
, m_firstNode(true)
{
}
template<typename Iterator, typename Traversal>
SceneGraphDownwardsIterator<Iterator, Traversal>::SceneGraphDownwardsIterator(
const SceneGraph& graph, SceneGraph::HierarchyStorageConstIterator graphIterator, Iterator iterator, bool rootIterator)
: m_ignoreDescendants(false)
, m_firstNode(true)
{
if (graph.GetHierarchyStorage().end() == graphIterator)
{
m_index = -1;
m_graph = nullptr;
}
else
{
m_graph = &graph;
m_index = static_cast<int32_t>(AZStd::distance(graph.GetHierarchyStorage().begin(), graphIterator));
m_iterator = rootIterator ? AZStd::next(iterator, m_index) : iterator;
}
}
template<typename Iterator, typename Traversal>
SceneGraphDownwardsIterator<Iterator, Traversal>::SceneGraphDownwardsIterator()
: m_graph(nullptr)
, m_index(-1)
, m_ignoreDescendants(false)
, m_firstNode(false)
{
}
template<typename Iterator, typename Traversal>
auto SceneGraphDownwardsIterator<Iterator, Traversal>::operator++()->SceneGraphDownwardsIterator &
{
MoveToNext(Traversal());
return *this;
}
template<typename Iterator, typename Traversal>
auto SceneGraphDownwardsIterator<Iterator, Traversal>::operator++(int)->SceneGraphDownwardsIterator
{
SceneGraphDownwardsIterator result = *this;
MoveToNext(Traversal());
return result;
}
template<typename Iterator, typename Traversal>
bool SceneGraphDownwardsIterator<Iterator, Traversal>::operator==(const SceneGraphDownwardsIterator& rhs) const
{
return m_graph == rhs.m_graph && m_index == rhs.m_index && m_firstNode == rhs.m_firstNode;
}
template<typename Iterator, typename Traversal>
bool SceneGraphDownwardsIterator<Iterator, Traversal>::operator!=(const SceneGraphDownwardsIterator& rhs) const
{
return m_graph != rhs.m_graph || m_index != rhs.m_index || m_firstNode != rhs.m_firstNode;
}
template<typename Iterator, typename Traversal>
auto SceneGraphDownwardsIterator<Iterator, Traversal>::operator*() const->reference
{
return *m_iterator;
}
template<typename Iterator, typename Traversal>
auto SceneGraphDownwardsIterator<Iterator, Traversal>::GetPointer(AZStd::true_type) const->pointer
{
return m_iterator;
}
template<typename Iterator, typename Traversal>
auto SceneGraphDownwardsIterator<Iterator, Traversal>::GetPointer(AZStd::false_type) const->pointer
{
return m_iterator.operator->();
}
template<typename Iterator, typename Traversal>
auto SceneGraphDownwardsIterator<Iterator, Traversal>::operator->() const->pointer
{
return GetPointer(typename AZStd::is_pointer<Iterator>::type());
}
template<typename Iterator, typename Traversal>
SceneGraph::HierarchyStorageConstIterator SceneGraphDownwardsIterator<Iterator, Traversal>::GetHierarchyIterator() const
{
if (m_index >= 0)
{
return AZStd::next(m_graph->GetHierarchyStorage().begin(), m_index);
}
else
{
return SceneGraph::HierarchyStorageConstIterator();
}
}
template<typename Iterator, typename Traversal>
void SceneGraphDownwardsIterator<Iterator, Traversal>::IgnoreNodeDescendants()
{
m_ignoreDescendants = true;
}
template<typename Iterator, typename Traversal>
void SceneGraphDownwardsIterator<Iterator, Traversal>::MoveToNext(DepthFirst)
{
AZ_Assert(m_graph, "Invalid iterator or moved passed end of list.");
SceneGraph::NodeHeader header = m_graph->GetHierarchyStorage().begin()[m_index];
if (!m_firstNode && header.HasSibling())
{
m_pending.push_back(static_cast<int32_t>(header.m_siblingIndex));
}
if (!m_ignoreDescendants && header.HasChild())
{
JumpTo(header.m_childIndex);
}
else if (!m_pending.empty())
{
JumpTo(m_pending.back());
m_pending.pop_back();
}
else
{
m_index = -1;
m_graph = nullptr;
}
m_ignoreDescendants = false;
m_firstNode = false;
}
template<typename Iterator, typename Traversal>
void SceneGraphDownwardsIterator<Iterator, Traversal>::MoveToNext(BreadthFirst)
{
AZ_Assert(m_graph, "Invalid iterator or moved passed end of list.");
SceneGraph::NodeHeader header = m_graph->GetHierarchyStorage().begin()[m_index];
if (!m_ignoreDescendants && header.HasChild())
{
m_pending.push_back(static_cast<int32_t>(header.m_childIndex));
}
if (!m_firstNode && header.HasSibling())
{
JumpTo(header.m_siblingIndex);
}
else if (!m_pending.empty())
{
JumpTo(m_pending.front());
m_pending.pop_front();
}
else
{
m_index = -1;
m_graph = nullptr;
}
m_ignoreDescendants = false;
m_firstNode = false;
}
template<typename Iterator, typename Traversal>
void SceneGraphDownwardsIterator<Iterator, Traversal>::JumpTo(int32_t index)
{
AZStd::advance(m_iterator, index - m_index);
m_index = index;
}
template<typename Traversal, typename Iterator>
SceneGraphDownwardsIterator<Iterator, Traversal> MakeSceneGraphDownwardsIterator(const SceneGraph& graph, Iterator iterator)
{
return SceneGraphDownwardsIterator<Iterator, Traversal>(graph, iterator);
}
template<typename Traversal, typename Iterator>
SceneGraphDownwardsIterator<Iterator, Traversal> MakeSceneGraphDownwardsIterator(
const SceneGraph& graph, SceneGraph::HierarchyStorageConstIterator graphIterator, Iterator iterator, bool rootIterator)
{
return SceneGraphDownwardsIterator<Iterator, Traversal>(graph, graphIterator, iterator, rootIterator);
}
template<typename Traversal, typename Iterator>
SceneGraphDownwardsIterator<Iterator, Traversal> MakeSceneGraphDownwardsIterator(
const SceneGraph& graph, SceneGraph::NodeIndex node, Iterator iterator, bool rootIterator)
{
return SceneGraphDownwardsIterator<Iterator, Traversal>(graph, graph.ConvertToHierarchyIterator(node), iterator, rootIterator);
}
template<typename Traversal, typename Iterator>
View<SceneGraphDownwardsIterator<Iterator, Traversal> > MakeSceneGraphDownwardsView(const SceneGraph& graph, Iterator iterator)
{
return View<SceneGraphDownwardsIterator<Iterator, Traversal> >(
SceneGraphDownwardsIterator<Iterator, Traversal>(graph, iterator),
SceneGraphDownwardsIterator<Iterator, Traversal>());
}
template<typename Traversal, typename Iterator>
View<SceneGraphDownwardsIterator<Iterator, Traversal> > MakeSceneGraphDownwardsView(
const SceneGraph& graph, SceneGraph::HierarchyStorageConstIterator graphIterator, Iterator iterator, bool rootIterator)
{
return View<SceneGraphDownwardsIterator<Iterator, Traversal> >(
SceneGraphDownwardsIterator<Iterator, Traversal>(graph, graphIterator, iterator, rootIterator),
SceneGraphDownwardsIterator<Iterator, Traversal>());
}
template<typename Traversal, typename Iterator>
View<SceneGraphDownwardsIterator<Iterator, Traversal> > MakeSceneGraphDownwardsView(
const SceneGraph& graph, SceneGraph::NodeIndex node, Iterator iterator, bool rootIterator)
{
return View<SceneGraphDownwardsIterator<Iterator, Traversal> >(
SceneGraphDownwardsIterator<Iterator, Traversal>(graph, graph.ConvertToHierarchyIterator(node), iterator, rootIterator),
SceneGraphDownwardsIterator<Iterator, Traversal>());
}
} // Views
} // Containers
} // SceneAPI
} // AZ
@@ -0,0 +1,109 @@
#pragma once
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include <stack>
#include <iterator>
#include <type_traits>
#include <AzCore/std/iterator.h>
#include <AzCore/std/typetraits/is_base_of.h>
#include <SceneAPI/SceneCore/Containers/Views/View.h>
#include <SceneAPI/SceneCore/Containers/SceneGraph.h>
namespace AZ
{
namespace SceneAPI
{
namespace Containers
{
namespace Views
{
// Iterator to traverse a SceneGraph from a given node upwards to the root.
// The given node will be included as the first returned value.
// Example:
// auto view = MakeSceneGraphUpwardsView(graph, graph.ConvertToHierarchyIterator(nodeIndex), graph.GetNameStorage().begin(), true);
// for (auto it : view)
// {
// printf("Node: %s\n", it.c_str());
// }
template<typename Iterator>
class SceneGraphUpwardsIterator
{
static_assert(AZStd::is_base_of<AZStd::bidirectional_iterator_tag, typename AZStd::iterator_traits<Iterator>::iterator_category>::value,
"SceneGraphUpwardsIterator needs at least a bidrectional iterator for its data iterator.");
public:
using value_type = typename AZStd::iterator_traits<Iterator>::value_type;
using difference_type = AZStd::ptrdiff_t;
using pointer = typename AZStd::iterator_traits<Iterator>::pointer;
using reference = typename AZStd::iterator_traits<Iterator>::reference;
using iterator_category = AZStd::forward_iterator_tag;
// Creates an iterator at a specified node in the hierarchy.
// graph: SceneGraph that will traversed.
// graphIterator: The node to start traversing from.
// iterator: The data iterator to be dereferenced from.
// rootIterator: If true the data iterator will be the first iterator from the data and
// this iterator will be moved forward to match the graph iterator. If false
// the graph iterator and the data iterator should be pointing to the same relative
// element.
SceneGraphUpwardsIterator(const SceneGraph& graph, SceneGraph::HierarchyStorageConstIterator graphIterator, Iterator iterator, bool rootIterator);
SceneGraphUpwardsIterator(const SceneGraphUpwardsIterator&) = default;
SceneGraphUpwardsIterator();
SceneGraphUpwardsIterator& operator=(const SceneGraphUpwardsIterator&) = default;
SceneGraphUpwardsIterator& operator++();
SceneGraphUpwardsIterator operator++(int);
bool operator==(const SceneGraphUpwardsIterator& rhs) const;
bool operator!=(const SceneGraphUpwardsIterator& rhs) const;
reference operator*() const;
pointer operator->() const;
SceneGraph::HierarchyStorageConstIterator GetHierarchyIterator() const;
private:
// For iterators that are raw pointers.
pointer GetPointer(AZStd::true_type) const;
// For all other types of iterator.
pointer GetPointer(AZStd::false_type) const;
void MoveToNext();
const SceneGraph* m_graph;
Iterator m_iterator;
int32_t m_index;
};
template<typename Iterator>
SceneGraphUpwardsIterator<Iterator> MakeSceneGraphUpwardsIterator(
const SceneGraph& graph, SceneGraph::HierarchyStorageConstIterator graphIterator, Iterator iterator, bool rootIterator);
template<typename Iterator>
SceneGraphUpwardsIterator<Iterator> MakeSceneGraphUpwardsIterator(
const SceneGraph& graph, SceneGraph::NodeIndex node, Iterator iterator, bool rootIterator);
template<typename Iterator>
View<SceneGraphUpwardsIterator<Iterator> > MakeSceneGraphUpwardsView(
const SceneGraph& graph, SceneGraph::HierarchyStorageConstIterator graphIterator, Iterator iterator, bool rootIterator);
template<typename Iterator>
View<SceneGraphUpwardsIterator<Iterator> > MakeSceneGraphUpwardsView(
const SceneGraph& graph, SceneGraph::NodeIndex node, Iterator iterator, bool rootIterator);
} // Views
} // Containers
} // SceneAPI
} // AZ
#include <SceneAPI/SceneCore/Containers/Views/SceneGraphUpwardsIterator.inl>
@@ -0,0 +1,153 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
namespace AZ
{
namespace SceneAPI
{
namespace Containers
{
namespace Views
{
template<typename Iterator>
SceneGraphUpwardsIterator<Iterator>::SceneGraphUpwardsIterator(
const SceneGraph& graph, SceneGraph::HierarchyStorageConstIterator graphIterator, Iterator iterator, bool rootIterator)
{
if (graph.GetHierarchyStorage().end() == graphIterator)
{
m_index = -1;
m_graph = nullptr;
}
else
{
m_graph = &graph;
m_index = static_cast<int32_t>(AZStd::distance(graph.GetHierarchyStorage().begin(), graphIterator));
m_iterator = rootIterator ? AZStd::next(iterator, m_index) : iterator;
}
}
template<typename Iterator>
SceneGraphUpwardsIterator<Iterator>::SceneGraphUpwardsIterator()
: m_graph(nullptr)
, m_index(-1)
{
}
template<typename Iterator>
auto SceneGraphUpwardsIterator<Iterator>::operator++()->SceneGraphUpwardsIterator &
{
MoveToNext();
return *this;
}
template<typename Iterator>
auto SceneGraphUpwardsIterator<Iterator>::operator++(int)->SceneGraphUpwardsIterator
{
SceneGraphUpwardsIterator result = *this;
MoveToNext();
return result;
}
template<typename Iterator>
bool SceneGraphUpwardsIterator<Iterator>::operator==(const SceneGraphUpwardsIterator& rhs) const
{
return m_graph == rhs.m_graph && m_index == rhs.m_index;
}
template<typename Iterator>
bool SceneGraphUpwardsIterator<Iterator>::operator!=(const SceneGraphUpwardsIterator& rhs) const
{
return m_graph != rhs.m_graph || m_index != rhs.m_index;
}
template<typename Iterator>
auto SceneGraphUpwardsIterator<Iterator>::operator*() const->reference
{
return *m_iterator;
}
template<typename Iterator>
auto SceneGraphUpwardsIterator<Iterator>::GetPointer(AZStd::true_type) const->pointer
{
return m_iterator;
}
template<typename Iterator>
auto SceneGraphUpwardsIterator<Iterator>::GetPointer(AZStd::false_type) const->pointer
{
return m_iterator.operator->();
}
template<typename Iterator>
auto SceneGraphUpwardsIterator<Iterator>::operator->() const->pointer
{
return GetPointer(typename AZStd::is_pointer<Iterator>::type());
}
template<typename Iterator>
SceneGraph::HierarchyStorageConstIterator SceneGraphUpwardsIterator<Iterator>::GetHierarchyIterator() const
{
return AZStd::next(m_graph->GetHierarchyStorage().begin(), m_index);
}
template<typename Iterator>
void SceneGraphUpwardsIterator<Iterator>::MoveToNext()
{
AZ_Assert(m_graph, "Invalid iterator or moved passed end of list.");
SceneGraph::NodeHeader header = m_graph->GetHierarchyStorage().begin()[m_index];
if (header.HasParent())
{
AZStd::advance(m_iterator, header.m_parentIndex - m_index);
m_index = header.m_parentIndex;
}
else
{
m_index = -1;
m_graph = nullptr;
}
}
template<typename Iterator>
SceneGraphUpwardsIterator<Iterator> MakeSceneGraphUpwardsIterator(
const SceneGraph& graph, SceneGraph::HierarchyStorageConstIterator graphIterator, Iterator iterator, bool rootIterator)
{
return SceneGraphUpwardsIterator<Iterator>(graph, graphIterator, iterator, rootIterator);
}
template<typename Iterator>
SceneGraphUpwardsIterator<Iterator> MakeSceneGraphUpwardsIterator(
const SceneGraph& graph, SceneGraph::NodeIndex node, Iterator iterator, bool rootIterator)
{
return SceneGraphUpwardsIterator<Iterator>(graph, graph.ConvertToHierarchyIterator(node), iterator, rootIterator);
}
template<typename Iterator>
View<SceneGraphUpwardsIterator<Iterator> > MakeSceneGraphUpwardsView(
const SceneGraph& graph, SceneGraph::HierarchyStorageConstIterator graphIterator, Iterator iterator, bool rootIterator)
{
return View<SceneGraphUpwardsIterator<Iterator> >(
SceneGraphUpwardsIterator<Iterator>(graph, graphIterator, iterator, rootIterator),
SceneGraphUpwardsIterator<Iterator>());
}
template<typename Iterator>
View<SceneGraphUpwardsIterator<Iterator> > MakeSceneGraphUpwardsView(
const SceneGraph& graph, SceneGraph::NodeIndex node, Iterator iterator, bool rootIterator)
{
return View<SceneGraphUpwardsIterator<Iterator> >(
SceneGraphUpwardsIterator<Iterator>(graph, graph.ConvertToHierarchyIterator(node), iterator, rootIterator),
SceneGraphUpwardsIterator<Iterator>());
}
} // Views
} // Containers
} // SceneAPI
} // AZ
@@ -0,0 +1,62 @@
#pragma once
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
namespace AZ
{
namespace SceneAPI
{
namespace Containers
{
namespace Views
{
// View combines begin and end iterators together in a single object.
// This reduces the number of functions that are needed to pass
// iterators from functions and avoids problems with mismatched
// iterators. It also makes it easier to use in ranged-based
// for-loops.
// Note that const correctness is enforced by the type of
// iterator passed, so all versions of begin and end return
// the same value.
template<typename Iterator>
class View
{
public:
using iterator = Iterator;
using const_iterator = Iterator;
View(Iterator begin, Iterator end);
Iterator begin();
Iterator end();
Iterator begin() const;
Iterator end() const;
Iterator cbegin() const;
Iterator cend() const;
private:
Iterator m_begin;
Iterator m_end;
};
template<typename Iterator>
View<Iterator> MakeView(Iterator begin, Iterator end)
{
return View<Iterator>(begin, end);
}
} // Views
} // Containers
} // SceneAPI
} // AZ
#include <SceneAPI/SceneCore/Containers/Views/View.inl>
@@ -0,0 +1,68 @@
#pragma once
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
namespace AZ
{
namespace SceneAPI
{
namespace Containers
{
namespace Views
{
template<typename Iterator>
View<Iterator>::View(Iterator begin, Iterator end)
: m_begin(begin)
, m_end(end)
{
}
template<typename Iterator>
Iterator View<Iterator>::begin()
{
return m_begin;
}
template<typename Iterator>
Iterator View<Iterator>::end()
{
return m_end;
}
template<typename Iterator>
Iterator View<Iterator>::begin() const
{
return m_begin;
}
template<typename Iterator>
Iterator View<Iterator>::end() const
{
return m_end;
}
template<typename Iterator>
Iterator View<Iterator>::cbegin() const
{
return m_begin;
}
template<typename Iterator>
Iterator View<Iterator>::cend() const
{
return m_end;
}
}; // Views
} // Containers
} // SceneAPI
} // AZ