libpressio 0.93.0
Loading...
Searching...
No Matches
options.h
Go to the documentation of this file.
1#ifndef PRESSIO_OPTIONS_CPP
2#define PRESSIO_OPTIONS_CPP
3
4#include <cwchar>
5#include <string>
6#include <map>
7#include <type_traits>
8#include <utility>
9#include <vector>
10#include <initializer_list>
11#include "pressio_options.h"
12#include "pressio_option.h"
13#include "pressio_compressor.h"
14#include "userptr.h"
16#include "std_compat/string_view.h"
17#include "std_compat/optional.h"
18#include "std_compat/variant.h"
19#include "std_compat/functional.h"
20#include "std_compat/language.h"
21#include <algorithm>
22
28namespace {
29using option_type = compat::variant<compat::monostate,
30 compat::optional<bool>,
31 compat::optional<int8_t>,
32 compat::optional<uint8_t>,
33 compat::optional<int16_t>,
34 compat::optional<uint16_t>,
35 compat::optional<int32_t>,
36 compat::optional<uint32_t>,
37 compat::optional<int64_t>,
38 compat::optional<uint64_t>,
39 compat::optional<float>,
40 compat::optional<double>,
41 compat::optional<std::string>,
42 compat::optional<userdata>,
43 compat::optional<std::vector<std::string>>,
44 compat::optional<pressio_data>,
45 compat::optional<pressio_dtype>,
46 compat::optional<pressio_thread_safety>
47 >;
48
49
50}
51
53template <class T>
55 return
56 std::is_same<T, bool>() ? pressio_option_bool_type :
57 std::is_same<T, int8_t>() ? pressio_option_int8_type :
58 std::is_same<T,uint8_t>() ? pressio_option_uint8_type :
59 std::is_same<T, int16_t>() ? pressio_option_int16_type :
60 std::is_same<T,uint16_t>() ? pressio_option_uint16_type :
61 std::is_same<T, int32_t>() ? pressio_option_int32_type :
62 std::is_same<T,uint32_t>() ? pressio_option_uint32_type :
63 std::is_same<T, int64_t>() ? pressio_option_int64_type :
64 std::is_same<T,uint64_t>() ? pressio_option_uint64_type :
65 std::is_same<T,float>() ? pressio_option_float_type :
66 std::is_same<T,double>() ? pressio_option_double_type :
67 std::is_same<T,std::string>() ? pressio_option_charptr_type :
68 std::is_same<T,const char*>() ? pressio_option_charptr_type :
69 std::is_same<T,const char**>() ? pressio_option_charptr_array_type :
70 std::is_same<T,std::vector<std::string>>() ? pressio_option_charptr_array_type :
71 std::is_same<T,pressio_data>() ? pressio_option_data_type :
72 std::is_same<T,pressio_dtype>() ? pressio_option_dtype_type :
74 ;
75}
76
80struct pressio_option final {
82 pressio_option()=default;
83
87 template<class T, typename = typename std::enable_if<
88 !std::is_same<T, pressio_conversion_safety>::value &&
89 !std::is_same<T, pressio_option>::value &&
90 !std::is_same<T, const char*>::value &&
91 !std::is_same<T, void*>::value &&
92 !std::is_same<T, compat::monostate>::value
93 >::type>
94 pressio_option(compat::optional<T> const& value): option(value) {}
95
99 template<class T, typename = typename std::enable_if<
100 !std::is_same<T, pressio_conversion_safety>::value &&
101 !std::is_same<T, pressio_option>::value &&
102 !std::is_same<T, const char*>::value &&
103 !std::is_same<T, void*>::value &&
104 !std::is_same<T, compat::monostate>::value
105 >::type>
106 pressio_option(compat::optional<T> && value): option(value) {}
107
111 template<class T, typename = typename std::enable_if<
112 !std::is_same<T, pressio_conversion_safety>::value &&
113 !std::is_same<T, pressio_option>::value &&
114 !std::is_same<T, const char*>::value &&
115 !std::is_same<T, compat::monostate>::value
116 >::type>
117 pressio_option(T const& value): option(compat::optional<T>(value)) {}
118
119 pressio_option(void* value): option(compat::optional<userdata>(userdata(value))) {}
120
124 pressio_option(compat::monostate value): option(value) { }
125
129 pressio_option(const char* value): option(std::string(value)) { }
130
135 template<class T>
136 pressio_option(std::initializer_list<T> ul): option(ul) {}
137
144
149
153 template <class T, typename std::enable_if<!(std::is_same<T,compat::monostate>::value || std::is_same<T,void*>::value),int>::type = 0>
154 bool holds_alternative() const {
155 return compat::holds_alternative<compat::optional<T>>(option);
156 }
157
161 template <class T, typename std::enable_if<std::is_same<T,void*>::value,int>::type = 0>
162 bool holds_alternative() const {
163 return compat::holds_alternative<compat::optional<userdata>>(option);
164 }
165
169 template <class T, typename std::enable_if<std::is_same<T,compat::monostate>::value,int>::type = 0>
170 bool holds_alternative() const {
171 return compat::holds_alternative<compat::monostate>(option);
172 }
173
177 template <class T>
178 compat::optional<T> const& get() const{
179 return compat::get<compat::optional<T>>(option);
180 }
181
186 template <class T, typename std::enable_if<std::is_same<T, void*>::value, int>::type = 0>
187 void* get_value() const{
188 return get<userdata>()->get();
189 }
190
191 template <class T, typename std::enable_if<!std::is_same<T, void*>::value, int>::type = 0>
192 T const& get_value() const{
193 return *get<T>();
194 }
195
199 bool has_value() const {
200 if (holds_alternative<compat::monostate>()) return false;
201 else {
202 switch(type())
203 {
205 return (bool)get<bool>();
207 return (bool)get<int8_t>();
209 return (bool)get<uint8_t>();
211 return (bool)get<int16_t>();
213 return (bool)get<uint16_t>();
215 return (bool)get<int32_t>();
217 return (bool)get<uint32_t>();
219 return (bool)get<int64_t>();
221 return (bool)get<uint64_t>();
223 return (bool)get<float>();
225 return (bool)get<double>();
227 return (bool)get<std::string>();
229 return (bool)get<userdata>();
231 return (bool)get<std::vector<std::string>>();
233 return (bool)get<pressio_data>();
235 return (bool)get<pressio_dtype>();
237 return (bool)get<pressio_thread_safety>();
239 default:
240 return false;
241 }
242 }
243 }
244
249 template <class T, typename std::enable_if<!std::is_same<T, void*>::value, bool>::type = false>
250 void set(T v) {
251 option = compat::optional<T>(v);
252 }
253
254 void set(void* v) {
255 option = compat::optional<userdata>(userdata(v));
256 }
257
263 switch(type)
264 {
266 option = compat::optional<std::string>();
267 break;
269 option = compat::optional<userdata>();
270 break;
272 option = compat::optional<bool>();
273 break;
275 option = compat::optional<int8_t>();
276 break;
278 option = compat::optional<uint8_t>();
279 break;
281 option = compat::optional<int16_t>();
282 break;
284 option = compat::optional<uint16_t>();
285 break;
287 option = compat::optional<int32_t>();
288 break;
290 option = compat::optional<uint32_t>();
291 break;
293 option = compat::optional<int64_t>();
294 break;
296 option = compat::optional<uint64_t>();
297 break;
299 option = compat::optional<float>();
300 break;
302 option = compat::optional<double>();
303 break;
305 option = compat::monostate{};
306 break;
308 option = compat::optional<std::vector<std::string>>();
309 break;
311 option = compat::optional<pressio_data>();
312 break;
314 option = compat::optional<pressio_thread_safety>();
315 break;
317 option = compat::optional<pressio_dtype>();
318 break;
319 }
320 }
321
325 bool operator==(pressio_option const& rhs) const {
326 return option == rhs.option;
327 }
328
335 auto casted = rhs.as(type(), safety);
336 if (casted.has_value()) {
337 *this = std::move(casted);
339 } else {
341 }
342 }
343
344 private:
345 option_type option;
346};
347
348
352struct pressio_options final {
353
355 using key_type = std::string;
358
365 pressio_options(pressio_options const& rhs)=default;
370 pressio_options(pressio_options && rhs) DEFAULTED_NOEXCEPT =default;
380 pressio_options& operator=(pressio_options && rhs) DEFAULTED_NOEXCEPT =default;
381
387 pressio_options(std::initializer_list<std::pair<const std::string, pressio_option>> opts): options(opts) {}
388
395 pressio_options_key_status key_status(std::string const& key) const {
396 auto it = options.find(key);
397 if(it == options.end()) {
399 } else if (it->second.has_value()) {
401 } else {
403 }
404 }
405
412 template <class StringType>
413 pressio_options_key_status key_status(StringType const& name, std::string const& key) const {
414 return key_status(format_name(name, key));
415 }
416
422 template <class StringType>
423 void set(StringType&& key, pressio_option const& value) {
424 options[std::forward<StringType>(key)] = value;
425 }
426
433 template <class StringType, class StringType2>
434 void set(StringType const& name, StringType2 const& key, pressio_option const& value) {
435 set(format_name(name, key), value);
436 }
437
438
445 template <class StringType>
447 switch(key_status(key))
448 {
451 return options[std::forward<StringType>(key)].cast_set(value, safety);
452 default:
454 }
455
456 }
457
465 template <class StringType, class StringType2>
466 enum pressio_options_key_status cast_set(StringType const& name, StringType2 const& key, pressio_option const& value, enum pressio_conversion_safety safety= pressio_conversion_implicit) {
467 return cast_set(format_name(name, key), value, safety);
468 }
469
475 template <class StringType>
476 void set_type(StringType && key, pressio_option_type type) {
477 options[std::forward<StringType>(key)].set_type(type);
478 }
479
486 template <class StringType, class StringType2>
487 void set_type(StringType const& name, StringType2 const& key, pressio_option_type type) {
488 set_type(format_name(name, key), type);
489 }
490
495 template<class StringType>
496 pressio_option const& get(StringType const& key) const {
497 return options.find(key)->second;
498 }
499
505 template <class StringType, class StringType2>
506 pressio_option const& get(compat::string_view const& name, StringType2 const& key) const {
507 std::string prefix_key;
508 for (auto path : search(name)) {
509 prefix_key = format_name(path, key);
510 if(options.find(prefix_key) != options.end()) {
511 return get(prefix_key);
512 }
513 }
514 return get(key);
515 }
516
525 template <class PointerType, class StringType>
526 enum pressio_options_key_status get(StringType const& key, compat::optional<PointerType>* value) const {
527 switch(key_status(key)){
529 {
530 auto variant = get(key);
531 if (variant.template holds_alternative<PointerType>()) {
532 *value = variant.template get<PointerType>();
534 } else {
536 }
537 }
538 break;
539 default:
540 //value does not exist
542 }
543 }
544
553 template <class PointerType, class StringType>
554 enum pressio_options_key_status get(StringType const& key, PointerType value) const {
555 using ValueType = typename std::remove_pointer<PointerType>::type;
556 switch(key_status(key)){
558 {
559 auto variant = get(key);
560 if (variant.template holds_alternative<ValueType>()) {
561 *value = variant.template get_value<ValueType>();
563 } else {
565 }
566 }
567 break;
568 default:
569 //value does not exist
571 }
572 }
573
583 template <class PointerType, class StringType, class StringType2>
584 enum pressio_options_key_status get(StringType const& name, StringType2 const& key, PointerType value) const {
585 std::string prefix_key;
586 for (auto path : search(name)) {
587 prefix_key = format_name(std::string(path), key);
588 if(options.find(prefix_key) != options.end()) {
589 return get(prefix_key, value);
590 }
591 }
592 return get(key, value);
593 }
594
604 template <class PointerType, class StringType>
605 enum pressio_options_key_status cast(StringType const& key, PointerType value, enum pressio_conversion_safety safety) const {
606 using ValueType = typename std::remove_pointer<PointerType>::type;
607 switch(key_status(key)){
609 {
610 auto variant = get(key);
611 auto converted = pressio_option(variant).as(pressio_type_to_enum<ValueType>(), safety);
612 if(converted.has_value()) {
613 *value = converted.template get_value<ValueType>();
615 } else {
617 }
618 }
619 break;
620 default:
621 //value does not exist
623 }
624 }
625
636 template <class PointerType, class StringType, class StringType2>
637 enum pressio_options_key_status cast(StringType const& name, StringType2 const& key, PointerType value, enum pressio_conversion_safety safety) const {
638 std::string prefix_key;
639 for (auto path : search(name)) {
640 prefix_key = format_name(path, key);
641 if(options.find(prefix_key) != options.end()) {
642 return cast(prefix_key, value, safety);
643 }
644 }
645 return cast(key, value, safety);
646 }
647
651 static std::vector<compat::string_view> search(compat::string_view const& value);
652
656 void clear() noexcept {
657 options.clear();
658 }
659
664 void copy_from(pressio_options const& o, bool ignore_empty=false) {
665 insert_or_assign(o.begin(), o.end(), ignore_empty);
666 }
667
668 private:
669
670 std::string format_name(std::string const& name, std::string const& key) const {
671 if(name == "") return key;
672 else return '/' + name + ':' + key;
673 }
674
675 std::map<std::string, pressio_option, compat::less<>> options;
676
677
678 public:
682 using iterator = typename decltype(options)::iterator;
686 using const_iterator = typename decltype(options)::const_iterator;
690 using value_type = typename decltype(options)::value_type;
691
696 return options.insert(it, value);
697 }
698
705 template <class InputIt>
706 void insert(InputIt begin, InputIt end){
707 options.insert(begin, end);
708 }
709
716 template <class InputIt>
717 void insert_or_assign(InputIt begin, InputIt end, bool ignore_empty){
718 std::for_each(begin, end, [this, ignore_empty](decltype(options)::const_reference it) {
719 if(ignore_empty && not it.second.has_value()) return;
720 options[it.first] = it.second;
721 });
722 }
723
724
725
729 auto begin() const -> decltype(std::begin(options)) {
730 return std::begin(options);
731 }
735 auto end() const -> decltype(std::end(options)) {
736 return std::end(options);
737 }
738
742 auto begin() -> decltype(std::begin(options)){
743 return std::begin(options);
744 }
748 auto end() -> decltype(std::end(options)){
749 return std::end(options);
750 }
751
753 size_t size() const {
754 return options.size();
755 }
756
762 iterator find(key_type const& key) {
763 return options.find(key);
764 }
765
771 const_iterator find(key_type const& key) const {
772 return options.find(key);
773 }
774
780 size_t erase(key_type const& key) {
781 return options.erase(key);
782 }
783
789 auto insert(value_type const& value) -> decltype(options.insert(value)) {
790 return options.insert(value);
791 }
792
796 bool operator==(pressio_options const& rhs) const {
797 return options == rhs.options;
798 }
799
801 size_t num_set() const {
802 return std::count_if(std::begin(options), std::end(options), [](decltype(options)::value_type const& key_option){
803 return key_option.second.has_value();
804 });
805 }
806};
807
808
809#endif
Definition: userptr.h:29
C++ pressio_data interface.
constexpr enum pressio_option_type pressio_type_to_enum()
Definition: options.h:54
Compress, decompress, and configure pressio and lossless compressors.
A single option value for a compressor.
A set of options for a compressor.
pressio_option_type
Definition: pressio_options.h:57
@ pressio_option_uint8_type
Definition: pressio_options.h:67
@ pressio_option_charptr_array_type
Definition: pressio_options.h:65
@ pressio_option_charptr_type
Definition: pressio_options.h:62
@ pressio_option_data_type
Definition: pressio_options.h:66
@ pressio_option_int64_type
Definition: pressio_options.h:72
@ pressio_option_uint64_type
Definition: pressio_options.h:71
@ pressio_option_unset_type
Definition: pressio_options.h:64
@ pressio_option_float_type
Definition: pressio_options.h:60
@ pressio_option_bool_type
Definition: pressio_options.h:73
@ pressio_option_double_type
Definition: pressio_options.h:61
@ pressio_option_uint32_type
Definition: pressio_options.h:58
@ pressio_option_int32_type
Definition: pressio_options.h:59
@ pressio_option_int16_type
Definition: pressio_options.h:70
@ pressio_option_userptr_type
Definition: pressio_options.h:63
@ pressio_option_int8_type
Definition: pressio_options.h:68
@ pressio_option_uint16_type
Definition: pressio_options.h:69
@ pressio_option_threadsafety_type
Definition: pressio_options.h:75
@ pressio_option_dtype_type
Definition: pressio_options.h:74
pressio_conversion_safety
Definition: pressio_options.h:39
@ pressio_conversion_implicit
Definition: pressio_options.h:43
pressio_options_key_status
Definition: pressio_options.h:27
@ pressio_options_key_does_not_exist
Definition: pressio_options.h:35
@ pressio_options_key_set
Definition: pressio_options.h:29
@ pressio_options_key_exists
Definition: pressio_options.h:32
Definition: options.h:80
pressio_option(const char *value)
Definition: options.h:129
pressio_option as(const enum pressio_option_type type, const enum pressio_conversion_safety safety=pressio_conversion_implicit) const
pressio_option(compat::optional< T > const &value)
Definition: options.h:94
bool holds_alternative() const
Definition: options.h:154
enum pressio_option_type type() const
pressio_option(std::initializer_list< T > ul)
Definition: options.h:136
void * get_value() const
Definition: options.h:187
bool has_value() const
Definition: options.h:199
pressio_option(compat::monostate value)
Definition: options.h:124
bool operator==(pressio_option const &rhs) const
Definition: options.h:325
pressio_option()=default
void set_type(pressio_option_type type)
Definition: options.h:262
pressio_option(T const &value)
Definition: options.h:117
void set(T v)
Definition: options.h:250
compat::optional< T > const & get() const
Definition: options.h:178
enum pressio_options_key_status cast_set(struct pressio_option const &rhs, enum pressio_conversion_safety safety=pressio_conversion_implicit)
Definition: options.h:334
pressio_option(compat::optional< T > &&value)
Definition: options.h:106
Definition: options.h:352
enum pressio_options_key_status get(StringType const &key, compat::optional< PointerType > *value) const
Definition: options.h:526
void set_type(StringType &&key, pressio_option_type type)
Definition: options.h:476
void set_type(StringType const &name, StringType2 const &key, pressio_option_type type)
Definition: options.h:487
auto insert(value_type const &value) -> decltype(options.insert(value))
Definition: options.h:789
enum pressio_options_key_status cast_set(StringType const &name, StringType2 const &key, pressio_option const &value, enum pressio_conversion_safety safety=pressio_conversion_implicit)
Definition: options.h:466
void set(StringType &&key, pressio_option const &value)
Definition: options.h:423
auto begin() const -> decltype(std::begin(options))
Definition: options.h:729
pressio_options & operator=(pressio_options const &rhs)=default
enum pressio_options_key_status get(StringType const &key, PointerType value) const
Definition: options.h:554
pressio_options(std::initializer_list< std::pair< const std::string, pressio_option > > opts)
Definition: options.h:387
void clear() noexcept
Definition: options.h:656
size_t num_set() const
Definition: options.h:801
typename decltype(options)::iterator iterator
Definition: options.h:682
iterator find(key_type const &key)
Definition: options.h:762
auto end() const -> decltype(std::end(options))
Definition: options.h:735
void insert_or_assign(InputIt begin, InputIt end, bool ignore_empty)
Definition: options.h:717
enum pressio_options_key_status cast(StringType const &key, PointerType value, enum pressio_conversion_safety safety) const
Definition: options.h:605
void set(StringType const &name, StringType2 const &key, pressio_option const &value)
Definition: options.h:434
iterator insert(const_iterator it, value_type const &value)
Definition: options.h:695
pressio_options_key_status key_status(StringType const &name, std::string const &key) const
Definition: options.h:413
size_t erase(key_type const &key)
Definition: options.h:780
size_t size() const
Definition: options.h:753
pressio_option const & get(compat::string_view const &name, StringType2 const &key) const
Definition: options.h:506
pressio_options(pressio_options const &rhs)=default
pressio_options()=default
std::string key_type
Definition: options.h:355
pressio_options & operator=(pressio_options &&rhs) DEFAULTED_NOEXCEPT=default
void copy_from(pressio_options const &o, bool ignore_empty=false)
Definition: options.h:664
void insert(InputIt begin, InputIt end)
Definition: options.h:706
enum pressio_options_key_status cast_set(StringType &&key, pressio_option const &value, enum pressio_conversion_safety safety=pressio_conversion_implicit)
Definition: options.h:446
pressio_option const & get(StringType const &key) const
Definition: options.h:496
enum pressio_options_key_status cast(StringType const &name, StringType2 const &key, PointerType value, enum pressio_conversion_safety safety) const
Definition: options.h:637
bool operator==(pressio_options const &rhs) const
Definition: options.h:796
auto end() -> decltype(std::end(options))
Definition: options.h:748
typename decltype(options)::const_iterator const_iterator
Definition: options.h:686
auto begin() -> decltype(std::begin(options))
Definition: options.h:742
pressio_options_key_status key_status(std::string const &key) const
Definition: options.h:395
enum pressio_options_key_status get(StringType const &name, StringType2 const &key, PointerType value) const
Definition: options.h:584
pressio_options(pressio_options &&rhs) DEFAULTED_NOEXCEPT=default
typename decltype(options)::value_type value_type
Definition: options.h:690
static std::vector< compat::string_view > search(compat::string_view const &value)
const_iterator find(key_type const &key) const
Definition: options.h:771