@@ -626,158 +626,46 @@ struct item_handle
626626 [[nodiscard]] item_value &value ();
627627 [[nodiscard]] const item_value &value () const ;
628628
629- [[nodiscard]] bool is_inapplicable () const noexcept { return value ().type () == item_value_type::INAPPLICABLE; }
630- [[nodiscard]] bool is_missing () const noexcept { return value ().type () == item_value_type::MISSING; }
631- [[nodiscard]] bool is_null () const noexcept { return is_inapplicable () or is_missing (); }
632-
633- [[nodiscard]] bool is_string () const noexcept { return value ().type () == item_value_type::TEXT; }
634-
635- [[nodiscard]] bool is_number_int () const noexcept { return value ().type () == item_value_type::INT; }
636- [[nodiscard]] bool is_number_float () const noexcept { return value ().type () == item_value_type::FLOAT; }
637- [[nodiscard]] bool is_number () const noexcept { return is_number_int () or is_number_float (); }
638-
639- [[nodiscard]] auto type () const { return value ().type (); }
640-
641- template <typename T>
642- [[nodiscard]] auto get () const
629+ [[nodiscard]] bool is_inapplicable () const noexcept
643630 {
644- if (empty ())
645- return T{};
646- else
647- return value ().template get <T>();
631+ return not empty () and value ().type () == item_value_type::INAPPLICABLE;
648632 }
649633
650- template <typename T>
651- [[nodiscard]] auto as () const
634+ [[nodiscard]] bool is_missing () const noexcept
652635 {
653- if (empty ())
654- return T{};
655- else
656- return value ().template get <T>();
636+ return empty () or value ().type () == item_value_type::MISSING;
657637 }
658638
659- [[nodiscard]] auto str () const
639+ [[nodiscard]] bool is_null () const noexcept
660640 {
661- return value (). str ();
641+ return empty () or is_inapplicable () or is_missing ();
662642 }
663643
664- [[nodiscard]] auto sv () const
644+ [[nodiscard]] bool is_string () const noexcept
665645 {
666- return value ().sv () ;
646+ return not empty () and value ().type () == item_value_type::TEXT ;
667647 }
668648
669- /* * Swap contents of @a a and @a b */
670- friend void swap (item_handle &a, item_handle &b) noexcept ;
671-
672- /* * Return the contents of this item as type @tparam T or, if not
673- * set, use @a dv as the default value.
674- */
675- template <typename T>
676- [[nodiscard]] auto value_or (const T &dv) const
649+ [[nodiscard]] bool is_number_int () const noexcept
677650 {
678- return empty () ? dv : this -> get <T>() ;
651+ return not empty () and value (). type () == item_value_type::INT ;
679652 }
680653
681- /* *
682- * @brief Compare the contents of this item with value @a value
683- * optionally ignoring character case, if @a icase is true.
684- * Returns 0 if both are equal, -1 if this sorts before @a value
685- * and 1 if this sorts after @a value
686- *
687- * @tparam T Type of the value @a value
688- * @param value The value to compare with
689- * @param icase Flag indicating if we should compare character case sensitive
690- * @return -1, 0 or 1
691- */
692-
693- [[nodiscard]] int compare (const item_value &value, bool icase = true ) const noexcept
654+ [[nodiscard]] bool is_number_float () const noexcept
694655 {
695- return this -> value ().compare (value, icase) ;
656+ return not empty () and value ().type () == item_value_type::FLOAT ;
696657 }
697658
698- [[nodiscard]] int compare ( const item_handle &value, bool icase = true ) const noexcept
659+ [[nodiscard]] bool is_number ( ) const noexcept
699660 {
700- return compare (value. value (), icase );
661+ return not empty () and ( is_number_int () or is_number_float () );
701662 }
702663
703- /* *
704- * @brief Compare the value contained with the value @a value and
705- * return true if both are equal.
706- */
707- [[nodiscard]] bool operator ==(const item_value &value) const noexcept
664+ [[nodiscard]] auto type () const
708665 {
709- // TODO: icase or not icase?
710- return this ->value ().compare (value) == 0 ;
666+ return empty () ? item_value_type::MISSING : value ().type ();
711667 }
712668
713- // We may not have C++20 yet...
714-
715- /* *
716- * @brief Compare the value contained with the value @a value and
717- * return true if both are not equal.
718- */
719- template <typename T>
720- [[nodiscard]] bool operator !=(const T &value) const noexcept
721- {
722- return not operator ==(value);
723- }
724-
725- /* *
726- * @brief Returns true if the content string is empty or
727- * only contains '.' meaning null or '?' meaning unknown
728- * in a mmCIF context
729- */
730- [[nodiscard]] bool empty () const ;
731-
732- /* * Easy way to test for an empty item */
733- explicit operator bool () const { return not empty (); }
734-
735- /* * Return a std::string_view for the contents */
736- [[nodiscard]] std::string_view text_ () const ;
737-
738- /* *
739- * @brief Construct a new item handle object
740- *
741- * @param cat Reference to category containing row
742- * @param row Reference to the row
743- * @param item_ix Item index
744- */
745- item_handle (category &cat, row &row, uint16_t item_ix)
746- : m_category(cat)
747- , m_row(row)
748- , m_item_ix(item_ix)
749- {
750- }
751-
752- private:
753- category &m_category;
754- row &m_row;
755- uint16_t m_item_ix;
756-
757- friend class parser ;
758-
759- void set (item_value value, bool updateLinked);
760- };
761-
762- struct const_item_handle
763- {
764- public:
765- const_item_handle () = delete ;
766-
767- [[nodiscard]] const item_value &value () const ;
768-
769- [[nodiscard]] bool is_inapplicable () const noexcept { return value ().type () == item_value_type::INAPPLICABLE; }
770- [[nodiscard]] bool is_missing () const noexcept { return value ().type () == item_value_type::MISSING; }
771- [[nodiscard]] bool is_null () const noexcept { return is_inapplicable () or is_missing (); }
772-
773- [[nodiscard]] bool is_string () const noexcept { return value ().type () == item_value_type::TEXT; }
774-
775- [[nodiscard]] bool is_number_int () const noexcept { return value ().type () == item_value_type::INT; }
776- [[nodiscard]] bool is_number_float () const noexcept { return value ().type () == item_value_type::FLOAT; }
777- [[nodiscard]] bool is_number () const noexcept { return is_number_int () or is_number_float (); }
778-
779- [[nodiscard]] auto type () const { return value ().type (); }
780-
781669 template <typename T>
782670 [[nodiscard]] auto get () const
783671 {
@@ -806,6 +694,9 @@ struct const_item_handle
806694 return value ().sv ();
807695 }
808696
697+ /* * Swap contents of @a a and @a b */
698+ friend void swap (item_handle &a, item_handle &b) noexcept ;
699+
809700 /* * Return the contents of this item as type @tparam T or, if not
810701 * set, use @a dv as the default value.
811702 */
@@ -832,7 +723,7 @@ struct const_item_handle
832723 return this ->value ().compare (value, icase);
833724 }
834725
835- [[nodiscard]] int compare (const const_item_handle &value, bool icase = true ) const noexcept
726+ [[nodiscard]] int compare (const item_handle &value, bool icase = true ) const noexcept
836727 {
837728 if (empty () and value.empty ())
838729 return 0 ;
@@ -876,24 +767,50 @@ struct const_item_handle
876767 /* * Easy way to test for an empty item */
877768 explicit operator bool () const { return not empty (); }
878769
770+ /* * Return a std::string_view for the contents */
771+ [[nodiscard]] std::string_view text_ () const ;
772+
879773 /* *
880774 * @brief Construct a new item handle object
881775 *
882776 * @param cat Reference to category containing row
883777 * @param row Reference to the row
884778 * @param item_ix Item index
885779 */
886- const_item_handle ( const category &cat, const row &row, uint16_t item_ix)
780+ item_handle ( category &cat, row &row, uint16_t item_ix)
887781 : m_category(cat)
888782 , m_row(row)
889783 , m_item_ix(item_ix)
890784 {
891785 }
892786
787+ /* *
788+ * @brief Construct a new item handle object
789+ *
790+ * @param cat Reference to category containing row
791+ * @param row Reference to the row
792+ * @param item_ix Item index
793+ */
794+ item_handle (const category &cat, const row &r, uint16_t item_ix)
795+ : m_category(const_cast <category &>(cat))
796+ , m_row(const_cast <row &>(r))
797+ , m_item_ix(item_ix)
798+ , m_is_const(true )
799+ {
800+ }
801+
802+ item_handle (const item_handle &) = delete ;
803+ item_handle &operator =(const item_handle &) = delete ;
804+
893805 private:
894- const category &m_category;
895- const row &m_row;
806+ category &m_category;
807+ row &m_row;
896808 uint16_t m_item_ix;
809+ bool m_is_const = false ;
810+
811+ friend class parser ;
812+
813+ void set (item_value value, bool updateLinked);
897814};
898815
899816} // namespace cif
0 commit comments