Fix build on old GCC.
[libdcp.git] / src / language_tag.h
index 8aa8a723db3ee8ea4923029c863a7463b3185d6c..6b4bebe63c7d43c0fca67adce4e270aa8c29eff3 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2020 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2020-2021 Carl Hetherington <cth@carlh.net>
 
     This file is part of libdcp.
 
     files in the program, then also delete it here.
 */
 
+
+/** @file  src/language_tag.cc
+ *  @brief LanguageTag class
+ */
+
+
 #ifndef LIBDCP_LANGUAGE_TAG_H
 #define LIBDCP_LANGUAGE_TAG_H
 
 
+#include <boost/filesystem.hpp>
 #include <boost/optional.hpp>
 #include <string>
 #include <vector>
@@ -66,7 +73,7 @@ public:
                }
        };
 
-       enum SubtagType
+       enum class SubtagType
        {
                LANGUAGE,
                SCRIPT,
@@ -78,10 +85,18 @@ public:
        class Subtag
        {
        public:
+               virtual ~Subtag () {}
+
                std::string subtag () const {
                        return _subtag;
                }
 
+               virtual SubtagType type () const = 0;
+
+               bool operator== (Subtag const& other) {
+                       return _subtag == other._subtag;
+               }
+
        protected:
                Subtag (std::string subtag, SubtagType type);
 
@@ -93,36 +108,52 @@ public:
        {
        public:
                LanguageSubtag (std::string subtag)
-                       : Subtag(subtag, LANGUAGE) {}
+                       : Subtag(subtag, SubtagType::LANGUAGE) {}
                LanguageSubtag (char const* subtag)
-                       : Subtag(subtag, LANGUAGE) {}
+                       : Subtag(subtag, SubtagType::LANGUAGE) {}
+
+               SubtagType type () const override {
+                       return SubtagType::LANGUAGE;
+               }
        };
 
        class ScriptSubtag : public Subtag
        {
        public:
                ScriptSubtag (std::string subtag)
-                       : Subtag(subtag, SCRIPT) {}
+                       : Subtag(subtag, SubtagType::SCRIPT) {}
                ScriptSubtag (char const* subtag)
-                       : Subtag(subtag, SCRIPT) {}
+                       : Subtag(subtag, SubtagType::SCRIPT) {}
+
+               SubtagType type () const override {
+                       return SubtagType::SCRIPT;
+               }
        };
 
        class RegionSubtag : public Subtag
        {
        public:
                RegionSubtag (std::string subtag)
-                       : Subtag(subtag, REGION) {}
+                       : Subtag(subtag, SubtagType::REGION) {}
                RegionSubtag (char const* subtag)
-                       : Subtag(subtag, REGION) {}
+                       : Subtag(subtag, SubtagType::REGION) {}
+
+               SubtagType type () const override {
+                       return SubtagType::REGION;
+               }
        };
 
        class VariantSubtag : public Subtag
        {
        public:
                VariantSubtag (std::string subtag)
-                       : Subtag(subtag, VARIANT) {}
+                       : Subtag(subtag, SubtagType::VARIANT) {}
                VariantSubtag (char const* subtag)
-                       : Subtag(subtag, VARIANT) {}
+                       : Subtag(subtag, SubtagType::VARIANT) {}
+
+               SubtagType type () const override {
+                       return SubtagType::VARIANT;
+               }
 
                bool operator== (VariantSubtag const& other) const;
                bool operator< (VariantSubtag const& other) const;
@@ -133,29 +164,73 @@ public:
        {
        public:
                ExtlangSubtag (std::string subtag)
-                       : Subtag(subtag, EXTLANG) {}
+                       : Subtag(subtag, SubtagType::EXTLANG) {}
                ExtlangSubtag (char const* subtag)
-                       : Subtag(subtag, EXTLANG) {}
+                       : Subtag(subtag, SubtagType::EXTLANG) {}
+
+               SubtagType type () const override {
+                       return SubtagType::EXTLANG;
+               }
 
                bool operator== (ExtlangSubtag const& other) const;
                bool operator< (ExtlangSubtag const& other) const;
        };
 
        LanguageTag () {}
-       LanguageTag (std::string tag);
+       explicit LanguageTag (std::string tag);
+
+       boost::optional<LanguageSubtag> language() const {
+               return _language;
+       }
 
        void set_language (LanguageSubtag language);
+
+       boost::optional<ScriptSubtag> script() const {
+               return _script;
+       }
+
        void set_script (ScriptSubtag script);
+
+       boost::optional<RegionSubtag> region() const {
+               return _region;
+       }
+
        void set_region (RegionSubtag region);
+
+       std::vector<VariantSubtag> variants() const {
+               return _variants;
+       }
+
        void set_variants (std::vector<VariantSubtag> variants);
        void add_variant (VariantSubtag variant);
+
+       std::vector<ExtlangSubtag> extlangs() const {
+               return _extlangs;
+       }
+
        void set_extlangs (std::vector<ExtlangSubtag> extlangs);
        void add_extlang (ExtlangSubtag extlang);
 
-       static std::vector<SubtagData> get_all (SubtagType type);
+       std::vector<std::pair<SubtagType, SubtagData>> subtags () const;
+
+       static std::vector<SubtagData> const& get_all (SubtagType type);
        static std::string subtag_type_name (SubtagType type);
 
+       static boost::optional<std::string> get_subtag_description (SubtagType, std::string subtag);
+       static boost::optional<SubtagData> get_subtag_data (SubtagType, std::string subtag);
+
+       template <class T>
+       static boost::optional<std::string> get_subtag_description (T s) {
+               return get_subtag_description (s.type(), s.subtag());
+       }
+
+       template <class T>
+       static boost::optional<SubtagData> get_subtag_data (T s) {
+               return get_subtag_data (s.type(), s.subtag());
+       }
+
 private:
+
        boost::optional<LanguageSubtag> _language;
        boost::optional<ScriptSubtag> _script;
        boost::optional<RegionSubtag> _region;
@@ -164,6 +239,19 @@ private:
 };
 
 
+extern bool operator==(dcp::LanguageTag const& a, dcp::LanguageTag const& b);
+extern bool operator!=(dcp::LanguageTag const& a, dcp::LanguageTag const& b);
+extern bool operator<(dcp::LanguageTag const& a, dcp::LanguageTag const& b);
+extern std::ostream& operator<<(std::ostream& os, dcp::LanguageTag const& tag);
+
+
+extern void load_language_tag_lists (boost::filesystem::path tags_directory);
+
+
+extern std::vector<std::pair<std::string, std::string>> dcnc_tags ();
+
+
 }
 
+
 #endif