sparrow 2.0.0
C++20 idiomatic APIs for the Apache Arrow Columnar Format
Loading...
Searching...
No Matches
timestamp_array.hpp
Go to the documentation of this file.
1// Copyright 2024 Man Group Operations Limited
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#pragma once
16
27#include "sparrow/u8_buffer.hpp"
33
34// tts : timestamp<std::chrono::seconds>
35// tsm : timestamp<std::chrono::milliseconds>
36// tsu : timestamp<std::chrono::microseconds>
37// tsn : timestamp<std::chrono::nanoseconds>
38
39namespace sparrow
40{
41 template <timestamp_type T>
42 class timestamp_array;
43
44 template <timestamp_type T>
60
66 template <typename T>
67 struct is_timestamp_array : std::false_type
68 {
69 };
70
76 template <typename T>
77 struct is_timestamp_array<timestamp_array<T>> : std::true_type
78 {
79 };
80
86 template <typename T>
88
96
104
105 namespace detail
106 {
107 template <>
109 {
110 [[nodiscard]] static constexpr sparrow::data_type get()
111 {
113 }
114 };
115
116 template <>
118 {
119 [[nodiscard]] static constexpr sparrow::data_type get()
120 {
122 }
123 };
124
125 template <>
127 {
128 [[nodiscard]] static constexpr sparrow::data_type get()
129 {
131 }
132 };
133
134 template <>
136 {
137 [[nodiscard]] static constexpr sparrow::data_type get()
138 {
140 }
141 };
142 }
143
196 template <timestamp_type T>
197 class timestamp_array final : public mutable_array_bitmap_base<timestamp_array<T>>
198 {
199 public:
200
203
205 using inner_value_type = typename inner_types::inner_value_type;
206 using inner_reference = typename inner_types::inner_reference;
207 using inner_const_reference = typename inner_types::inner_const_reference;
208
210 using bitmap_reference = typename base_type::bitmap_reference;
214 using bitmap_range = typename base_type::bitmap_range;
216
220
224
225 using value_iterator = typename base_type::value_iterator;
226 using const_value_iterator = typename base_type::const_value_iterator;
227
228 using iterator = typename base_type::iterator;
229 using const_iterator = typename base_type::const_iterator;
230
231 using functor_type = typename inner_types::functor_type;
232 using const_functor_type = typename inner_types::const_functor_type;
233
234 using inner_value_type_duration = inner_value_type::duration;
235 using buffer_inner_value_type = inner_value_type_duration::rep;
238
252
292 template <class... Args>
294 constexpr explicit timestamp_array(Args&&... args)
295 : base_type(create_proxy(std::forward<Args>(args)...))
296 , m_timezone(get_timezone(this->get_arrow_proxy()))
297 , m_data_access(this->get_arrow_proxy(), DATA_BUFFER_INDEX)
298 {
299 }
300
315 template <input_metadata_container METADATA_RANGE = std::vector<metadata_pair>>
317 const date::time_zone* timezone,
318 std::initializer_list<inner_value_type> init,
319 std::optional<std::string_view> name = std::nullopt,
320 std::optional<METADATA_RANGE> metadata = std::nullopt
321 )
322 : base_type(create_proxy(timezone, init, std::move(name), std::move(metadata)))
323 , m_timezone(timezone)
324 , m_data_access(this->get_arrow_proxy(), DATA_BUFFER_INDEX)
325 {
326 }
327
338 constexpr timestamp_array(const timestamp_array& rhs);
339
352
363
375
376 private:
377
389 [[nodiscard]] constexpr inner_reference value(size_type i);
390
403 [[nodiscard]] constexpr inner_const_reference value(size_type i) const;
404
412 [[nodiscard]] constexpr value_iterator value_begin();
413
421 [[nodiscard]] constexpr value_iterator value_end();
422
430 [[nodiscard]] constexpr const_value_iterator value_cbegin() const;
431
439 [[nodiscard]] constexpr const_value_iterator value_cend() const;
440
442
479 template <input_metadata_container METADATA_RANGE>
480 [[nodiscard]] static arrow_proxy create_proxy(
481 const date::time_zone* timezone,
482 size_type n,
483 std::optional<std::string_view> name = std::nullopt,
484 std::optional<METADATA_RANGE> metadata = std::nullopt
485 );
486
487 //
515 template <
517 input_metadata_container METADATA_RANGE = std::vector<metadata_pair>>
518 [[nodiscard]] static auto create_proxy(
519 const date::time_zone* timezone,
522 std::optional<std::string_view> name = std::nullopt,
523 std::optional<METADATA_RANGE> metadata = std::nullopt
524 ) -> arrow_proxy;
525
554 template <std::ranges::input_range R, input_metadata_container METADATA_RANGE = std::vector<metadata_pair>>
555 requires std::convertible_to<std::ranges::range_value_t<R>, T>
556 [[nodiscard]] static auto create_proxy(
557 const date::time_zone* timezone,
558 R&& range,
559 bool nullable = true,
560 std::optional<std::string_view> name = std::nullopt,
561 std::optional<METADATA_RANGE> metadata = std::nullopt
562 ) -> arrow_proxy;
563
564
590 template <typename U, input_metadata_container METADATA_RANGE = std::vector<metadata_pair>>
591 requires std::convertible_to<U, T>
592 [[nodiscard]] static arrow_proxy create_proxy(
593 const date::time_zone* timezone,
594 size_type n,
595 const U& value = U{},
596 std::optional<std::string_view> name = std::nullopt,
597 std::optional<METADATA_RANGE> metadata = std::nullopt
598 );
599
630 template <
631 std::ranges::input_range VALUE_RANGE,
632 validity_bitmap_input VALIDITY_RANGE,
633 input_metadata_container METADATA_RANGE = std::vector<metadata_pair>>
634 requires(std::convertible_to<std::ranges::range_value_t<VALUE_RANGE>, T>)
635 [[nodiscard]] static arrow_proxy create_proxy(
636 const date::time_zone* timezone,
637 VALUE_RANGE&&,
638 VALIDITY_RANGE&&,
639 std::optional<std::string_view> name = std::nullopt,
640 std::optional<METADATA_RANGE> metadata = std::nullopt
641 );
642
671 template <std::ranges::input_range R, input_metadata_container METADATA_RANGE = std::vector<metadata_pair>>
672 requires std::is_same_v<std::ranges::range_value_t<R>, nullable<T>>
673 [[nodiscard]] static arrow_proxy create_proxy(
674 const date::time_zone* timezone,
675 R&&,
676 std::optional<std::string_view> name = std::nullopt,
677 std::optional<METADATA_RANGE> metadata = std::nullopt
678 );
679
721 template <input_metadata_container METADATA_RANGE = std::vector<metadata_pair>>
722 [[nodiscard]] static arrow_proxy create_proxy_impl(
723 const date::time_zone* timezone,
724 u8_buffer<buffer_inner_value_type>&& data_buffer,
725 std::optional<validity_bitmap>&& bitmap,
726 std::optional<std::string_view> name = std::nullopt,
727 std::optional<METADATA_RANGE> metadata = std::nullopt
728 );
729
731
732 // Modifiers
733
745 constexpr void resize_values(size_type new_length, inner_value_type value);
746
761 constexpr value_iterator
762 insert_value(const_value_iterator pos, inner_value_type value, size_type count);
763
781 template <mpl::iterator_of_type<typename timestamp_array<T>::inner_value_type> InputIt>
782 constexpr auto insert_values(const_value_iterator pos, InputIt first, InputIt last) -> value_iterator
783 {
784 const auto input_range = std::ranges::subrange(first, last);
785 const auto values = input_range | std::views::transform(extract_duration);
786 const size_t idx = static_cast<size_t>(std::distance(value_cbegin(), pos));
787 m_data_access.insert_values(idx, values.begin(), values.end());
788 return sparrow::next(value_begin(), idx);
789 }
790
806 constexpr value_iterator erase_values(const_value_iterator pos, size_type count);
807
821 constexpr void assign(const T& rhs, size_type index);
822
836 constexpr void assign(T&& rhs, size_type index);
837
844 [[nodiscard]] static constexpr auto extract_duration(const inner_value_type& timestamp)
846 {
847 return timestamp.get_sys_time().time_since_epoch();
848 }
849
850 const date::time_zone* m_timezone;
851 details::primitive_data_access<inner_value_type_duration> m_data_access;
852
853 static constexpr size_type DATA_BUFFER_INDEX = 1;
854 friend class timestamp_reference<self_type>;
855 friend base_type;
858 friend functor_type;
859 friend const_functor_type;
860 };
861
862 template <timestamp_type T>
864 : base_type(rhs)
865 , m_timezone(rhs.m_timezone)
866 , m_data_access(this->get_arrow_proxy(), DATA_BUFFER_INDEX)
867 {
868 }
869
870 template <timestamp_type T>
872 {
874 m_timezone = rhs.m_timezone;
875 m_data_access.reset_proxy(this->get_arrow_proxy());
876 return *this;
877 }
878
879 template <timestamp_type T>
881 : base_type(std::move(rhs))
882 , m_timezone(rhs.m_timezone)
883 , m_data_access(this->get_arrow_proxy(), DATA_BUFFER_INDEX)
884 {
885 }
886
887 template <timestamp_type T>
889 {
890 base_type::operator=(std::move(rhs));
891 m_timezone = rhs.m_timezone;
892 m_data_access.reset_proxy(this->get_arrow_proxy());
893 return *this;
894 }
895
896 template <timestamp_type T>
898 : base_type(std::move(proxy))
899 , m_timezone(get_timezone(this->get_arrow_proxy()))
900 , m_data_access(this->get_arrow_proxy(), DATA_BUFFER_INDEX)
901 {
902 }
903
904 template <timestamp_type T>
905 template <validity_bitmap_input R, input_metadata_container METADATA_RANGE>
906 auto timestamp_array<T>::create_proxy(
907 const date::time_zone* timezone,
909 R&& bitmap_input,
910 std::optional<std::string_view> name,
911 std::optional<METADATA_RANGE> metadata
912 ) -> arrow_proxy
913 {
914 const auto size = data_buffer.size();
915 validity_bitmap bitmap = ensure_validity_bitmap(size, std::forward<R>(bitmap_input));
916 return create_proxy_impl(
917 timezone,
918 std::forward<u8_buffer<buffer_inner_value_type>>(data_buffer),
919 std::move(bitmap),
920 std::move(name),
921 std::move(metadata)
922 );
923 }
924
925 template <timestamp_type T>
926 template <std::ranges::input_range VALUE_RANGE, validity_bitmap_input VALIDITY_RANGE, input_metadata_container METADATA_RANGE>
927 requires(std::convertible_to<std::ranges::range_value_t<VALUE_RANGE>, T>)
928 arrow_proxy timestamp_array<T>::create_proxy(
929 const date::time_zone* timezone,
930 VALUE_RANGE&& values,
931 VALIDITY_RANGE&& validity_input,
932 std::optional<std::string_view> name,
933 std::optional<METADATA_RANGE> metadata
934 )
935 {
936 constexpr auto extract_duration_count = [](const auto& v)
937 {
938 return v.get_sys_time().time_since_epoch().count();
939 };
940
941 const auto range = values | std::views::transform(extract_duration_count);
942
943 u8_buffer<buffer_inner_value_type> data_buffer(range);
944 return create_proxy(
945 timezone,
946 std::move(data_buffer),
947 std::forward<VALIDITY_RANGE>(validity_input),
948 std::move(name),
949 std::move(metadata)
950 );
951 }
952
953 template <timestamp_type T>
954 template <typename U, input_metadata_container METADATA_RANGE>
955 requires std::convertible_to<U, T>
956 arrow_proxy timestamp_array<T>::create_proxy(
957 const date::time_zone* timezone,
958 size_type n,
959 const U& value,
960 std::optional<std::string_view> name,
961 std::optional<METADATA_RANGE> metadata
962 )
963 {
964 // Extract duration count from the timestamp value
965 const auto duration_count = value.get_sys_time().time_since_epoch().count();
966 u8_buffer<buffer_inner_value_type> data_buffer(n, duration_count);
967 return create_proxy(timezone, std::move(data_buffer), std::move(name), std::move(metadata));
968 }
969
970 template <timestamp_type T>
971 template <std::ranges::input_range R, input_metadata_container METADATA_RANGE>
972 requires std::convertible_to<std::ranges::range_value_t<R>, T>
973 arrow_proxy timestamp_array<T>::create_proxy(
974 const date::time_zone* timezone,
975 R&& range,
976 bool nullable,
977 std::optional<std::string_view> name,
978 std::optional<METADATA_RANGE> metadata
979 )
980 {
981 constexpr auto extract_duration_count = [](const auto& v)
982 {
983 return v.get_sys_time().time_since_epoch().count();
984 };
985
986 std::optional<validity_bitmap> bitmap = nullable ? std::make_optional<validity_bitmap>(
987 nullptr,
988 0,
990 )
991 : std::nullopt;
992 const auto values = range | std::views::transform(extract_duration_count);
993 u8_buffer<buffer_inner_value_type> data_buffer(values);
994 return self_type::create_proxy_impl(
995 timezone,
996 std::move(data_buffer),
997 std::move(bitmap),
998 std::move(name),
999 std::move(metadata)
1000 );
1001 }
1002
1003 // range of nullable values
1004 template <timestamp_type T>
1005 template <std::ranges::input_range R, input_metadata_container METADATA_RANGE>
1006 requires std::is_same_v<std::ranges::range_value_t<R>, nullable<T>>
1007 arrow_proxy timestamp_array<T>::create_proxy(
1008 const date::time_zone* timezone,
1009 R&& range,
1010 std::optional<std::string_view> name,
1011 std::optional<METADATA_RANGE> metadata
1012 )
1013 { // split into values and is_non_null ranges
1014 auto values = range
1015 | std::views::transform(
1016 [](const auto& v)
1017 {
1018 return v.get();
1019 }
1020 );
1021 auto is_non_null = range
1022 | std::views::transform(
1023 [](const auto& v)
1024 {
1025 return v.has_value();
1026 }
1027 );
1028 return self_type::create_proxy(timezone, values, is_non_null, std::move(name), std::move(metadata));
1029 }
1030
1031 template <timestamp_type T>
1032 template <input_metadata_container METADATA_RANGE>
1033 arrow_proxy timestamp_array<T>::create_proxy_impl(
1034 const date::time_zone* timezone,
1036 std::optional<validity_bitmap>&& bitmap,
1037 std::optional<std::string_view> name,
1038 std::optional<METADATA_RANGE> metadata
1039 )
1040 {
1041 const auto size = data_buffer.size();
1042 const auto null_count = bitmap.has_value() ? bitmap->null_count() : 0;
1043
1045 format += timezone->name();
1046
1048
1049 const std::optional<std::unordered_set<sparrow::ArrowFlag>>
1050 flags = bitmap.has_value()
1051 ? std::make_optional<std::unordered_set<sparrow::ArrowFlag>>({ArrowFlag::NULLABLE})
1052 : std::nullopt;
1053
1054 // create arrow schema and array
1055 ArrowSchema schema = make_arrow_schema(
1056 std::move(format), // format
1057 std::move(name), // name
1058 std::move(metadata), // metadata
1059 flags, // flags
1060 nullptr, // children
1061 children_ownership, // children ownership
1062 nullptr, // dictionary,
1063 true // dictionary ownership
1064 );
1065
1066 std::vector<buffer<uint8_t>> buffers{
1067 bitmap.has_value() ? std::move(bitmap.value()).extract_storage()
1069 std::move(data_buffer).extract_storage()
1070 };
1071
1072 // create arrow array
1073 ArrowArray arr = make_arrow_array(
1074 static_cast<std::int64_t>(size), // length
1075 static_cast<int64_t>(null_count),
1076 0, // offset
1077 std::move(buffers),
1078 nullptr, // children
1079 children_ownership, // children ownership
1080 nullptr, // dictionary
1081 true // dicitonary ownership
1082 );
1083 return arrow_proxy(std::move(arr), std::move(schema));
1084 }
1085
1086 template <timestamp_type T>
1087 constexpr void timestamp_array<T>::assign(const T& rhs, size_type index)
1088 {
1089 SPARROW_ASSERT_TRUE(index < this->size());
1090 m_data_access.value(index) = extract_duration(rhs);
1091 }
1092
1093 template <timestamp_type T>
1094 constexpr void timestamp_array<T>::assign(T&& rhs, size_type index)
1095 {
1096 SPARROW_ASSERT_TRUE(index < this->size());
1097 m_data_access.value(index) = extract_duration(rhs);
1098 }
1099
1100 template <timestamp_type T>
1101 constexpr auto timestamp_array<T>::value(size_type i) -> inner_reference
1102 {
1103 SPARROW_ASSERT_TRUE(i < this->size());
1104 return inner_reference(this, i);
1105 }
1106
1107 template <timestamp_type T>
1108 constexpr auto timestamp_array<T>::value(size_type i) const -> inner_const_reference
1109 {
1110 SPARROW_ASSERT_TRUE(i < this->size());
1111 const auto& val = m_data_access.value(i);
1112 using time_duration = typename T::duration;
1113 const auto sys_time = std::chrono::sys_time<time_duration>{val};
1114 return T{m_timezone, sys_time};
1115 }
1116
1117 template <timestamp_type T>
1118 constexpr auto timestamp_array<T>::value_begin() -> value_iterator
1119 {
1120 return value_iterator(functor_type(this), 0);
1121 }
1122
1123 template <timestamp_type T>
1124 constexpr auto timestamp_array<T>::value_end() -> value_iterator
1125 {
1126 return value_iterator(functor_type(this), this->size());
1127 }
1128
1129 template <timestamp_type T>
1130 constexpr auto timestamp_array<T>::value_cbegin() const -> const_value_iterator
1131 {
1132 return const_value_iterator(const_functor_type(this), 0);
1133 }
1134
1135 template <timestamp_type T>
1136 constexpr auto timestamp_array<T>::value_cend() const -> const_value_iterator
1137 {
1138 return const_value_iterator(const_functor_type(this), this->size());
1139 }
1140
1141 template <timestamp_type T>
1142 constexpr void timestamp_array<T>::resize_values(size_type new_length, inner_value_type value)
1143 {
1144 m_data_access.resize_values(new_length, extract_duration(value));
1145 }
1146
1147 template <timestamp_type T>
1148 constexpr auto
1149 timestamp_array<T>::insert_value(const_value_iterator pos, inner_value_type value, size_type count)
1150 -> value_iterator
1151 {
1152 SPARROW_ASSERT_TRUE(pos <= value_cend());
1153 const size_t idx = static_cast<size_t>(std::distance(value_cbegin(), pos));
1154 m_data_access.insert_value(idx, extract_duration(value), count);
1155 return value_iterator(functor_type(this), idx);
1156 }
1157
1158 template <timestamp_type T>
1159 constexpr auto timestamp_array<T>::erase_values(const_value_iterator pos, size_type count) -> value_iterator
1160 {
1161 SPARROW_ASSERT_TRUE(pos < value_cend());
1162 const size_t idx = static_cast<size_t>(std::distance(value_cbegin(), pos));
1163 m_data_access.erase_values(idx, count);
1164 return value_iterator(functor_type(this), idx);
1165 }
1166}
typename base_type::const_bitmap_range const_bitmap_range
typename base_type::bitmap_iterator bitmap_iterator
typename base_type::iterator_tag iterator_tag
typename base_type::const_bitmap_iterator const_bitmap_iterator
constexpr array_bitmap_base_impl & operator=(const array_bitmap_base_impl &)
std::conditional_t< is_mutable, mutable_array_base< D >, array_crtp_base< D > > base_type
typename base_type::bitmap_const_reference bitmap_const_reference
typename base_type::bitmap_type bitmap_type
typename base_type::difference_type difference_type
Object that owns a piece of contiguous memory.
Definition buffer.hpp:114
xsimd::aligned_allocator< T > default_allocator
Definition buffer.hpp:126
constexpr auto insert_values(const_value_iterator pos, InputIt first, InputIt last) -> value_iterator
storage_type extract_storage() noexcept
Extracts the underlying storage (move operation).
constexpr size_type null_count() const noexcept
Returns the number of bits set to false (null/invalid).
typename storage_type::default_allocator default_allocator
A view that repeats a value a given number of times.
Array implementation for storing timestamp values with timezone information.
mutable_array_bitmap_base< self_type > base_type
typename inner_types::inner_reference inner_reference
constexpr timestamp_array(timestamp_array &&rhs)
Move constructor.
constexpr timestamp_array(const timestamp_array &rhs)
Copy constructor.
timestamp_array(arrow_proxy)
Constructs timestamp array from Arrow proxy.
typename base_type::const_bitmap_iterator const_bitmap_iterator
typename base_type::const_value_iterator const_value_iterator
pointer_iterator< const buffer_inner_value_type * > buffer_inner_const_value_iterator
typename base_type::bitmap_const_reference bitmap_const_reference
constexpr timestamp_array & operator=(const timestamp_array &rhs)
Copy assignment operator.
pointer_iterator< buffer_inner_value_type * > buffer_inner_value_iterator
typename base_type::const_bitmap_range const_bitmap_range
constexpr timestamp_array(Args &&... args)
Generic constructor for creating timestamp arrays from various inputs.
nullable< inner_const_reference, bitmap_const_reference > const_reference
typename inner_types::inner_const_reference inner_const_reference
nullable< inner_reference, bitmap_reference > reference
typename base_type::bitmap_reference bitmap_reference
constexpr timestamp_array(const date::time_zone *timezone, std::initializer_list< inner_value_type > init, std::optional< std::string_view > name=std::nullopt, std::optional< METADATA_RANGE > metadata=std::nullopt)
Constructs timestamp array from initializer list.
constexpr timestamp_array & operator=(timestamp_array &&rhs)
Move assignment operator.
typename inner_types::const_functor_type const_functor_type
typename inner_types::inner_value_type inner_value_type
Implementation of reference to inner type used for layout L.
This buffer class is used as storage buffer for all sparrow arrays.
Concept for input containers that can provide metadata pairs.
Definition metadata.hpp:332
Concept defining valid input types for validity bitmap creation.
#define SPARROW_ASSERT_TRUE(expr__)
constexpr std::size_t size(typelist< T... >={})
Gets the count of types contained in a typelist.
Definition mp_utils.hpp:216
constexpr bool excludes_copy_and_move_ctor_v
Convenience variable template for excludes_copy_and_move_ctor.
array_bitmap_base_impl< D, true > mutable_array_bitmap_base
Convenient alias for arrays with mutable validity bitmaps.
ArrowSchema make_arrow_schema(F format, N name, std::optional< M > metadata, std::optional< std::unordered_set< ArrowFlag > > flags, ArrowSchema **children, const CHILDREN_OWNERSHIP &children_ownership, ArrowSchema *dictionary, bool dictionary_ownership)
Creates an ArrowSchema owned by a unique_ptr and holding the provided data.
timestamp< std::chrono::microseconds > timestamp_microsecond
constexpr std::string_view data_type_to_format(data_type type)
timestamp< std::chrono::nanoseconds > timestamp_nanosecond
constexpr InputIt next(InputIt it, Distance n)
Definition iterator.hpp:503
SPARROW_API const date::time_zone * get_timezone(const arrow_proxy &proxy)
timestamp_array< timestamp_second > timestamp_seconds_array
Type aliases for timestamp arrays with common durations.
date::zoned_time< Duration, TimeZonePtr > timestamp
constexpr bool is_timestamp_array_v
Variable template for convenient access to is_timestamp_array.
ArrowArray make_arrow_array(int64_t length, int64_t null_count, int64_t offset, B buffers, ArrowArray **children, const CHILDREN_OWNERSHIP &children_ownership, ArrowArray *dictionary, bool dictionary_ownership)
Creates an ArrowArray.
dynamic_bitset< std::uint8_t > validity_bitmap
Type alias for a validity bitmap using 8-bit storage blocks.
timestamp_array< timestamp_nanosecond > timestamp_nanoseconds_array
timestamp< std::chrono::seconds > timestamp_second
Type aliases for common timestamp durations.
validity_bitmap ensure_validity_bitmap(std::size_t size, R &&validity_input)
Ensures a validity bitmap of the specified size from various input types.
timestamp< std::chrono::milliseconds > timestamp_millisecond
data_type
Runtime identifier of arrow data types, usually associated with raw bytes with the associated value.
timestamp_array< timestamp_microsecond > timestamp_microseconds_array
timestamp_array< timestamp_millisecond > timestamp_milliseconds_array
Extensions to the C++ standard library.
functor_index_iterator< functor_type > value_iterator
functor_index_iterator< const_functor_type > const_value_iterator
detail::layout_value_functor< self_type, inner_reference > functor_type
detail::layout_value_functor< const self_type, inner_const_reference > const_functor_type
Base class for array_inner_types specializations.
Traits class that must be specialized by array implementations.
Metafunction for retrieving the data_type of a typed array.
Type trait to check if a type is a timestamp_array.