From 6218b88920120dea23d605856b9d27f9deb4746c Mon Sep 17 00:00:00 2001
From: Star Rauchenberger <fefferburbia@gmail.com>
Date: Wed, 14 Dec 2022 10:19:40 -0500
Subject: Migrate from mpark::variant to std::variant

---
 CMakeLists.txt        |   7 +--
 lib/database.cpp      |   8 ++--
 lib/filter.cpp        | 118 +++++++++++++++++++++++++-------------------------
 lib/filter.h          |  10 ++---
 lib/form.cpp          |  10 ++---
 lib/frame.cpp         |   6 +--
 lib/notion.cpp        |  12 ++---
 lib/part.cpp          |  26 +++++------
 lib/part.h            |   6 +--
 lib/pronunciation.cpp |  14 +++---
 lib/statement.cpp     |  56 ++++++++++++------------
 lib/statement.h       |  10 ++---
 lib/token.cpp         |  40 ++++++++---------
 lib/token.h           |   6 +--
 lib/word.cpp          |  14 +++---
 vendor/hkutil         |   2 +-
 16 files changed, 171 insertions(+), 174 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 2adad19..e00b490 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -4,8 +4,6 @@ project (verbly)
 find_package(PkgConfig)
 pkg_check_modules(sqlite3 sqlite3>=3.8.3 REQUIRED)
 
-set(CMAKE_BUILD_TYPE Debug)
-
 add_library(verbly
   lib/filter.cpp
   lib/field.cpp
@@ -21,9 +19,8 @@ add_library(verbly
 
 target_include_directories(verbly PUBLIC
   lib
-  vendor/hkutil
-  vendor/hkutil/vendor)
+  vendor/hkutil)
 
-set_property(TARGET verbly PROPERTY CXX_STANDARD 11)
+set_property(TARGET verbly PROPERTY CXX_STANDARD 17)
 set_property(TARGET verbly PROPERTY CXX_STANDARD_REQUIRED ON)
 target_link_libraries(verbly ${sqlite3_LIBRARIES})
diff --git a/lib/database.cpp b/lib/database.cpp
index 96eed45..d5ff37e 100644
--- a/lib/database.cpp
+++ b/lib/database.cpp
@@ -12,8 +12,8 @@ namespace verbly {
     hatkirby::row version =
       ppdb_.queryFirst("SELECT major, minor FROM version");
 
-    major_ = mpark::get<int>(version[0]);
-    minor_ = mpark::get<int>(version[1]);
+    major_ = std::get<int>(version[0]);
+    minor_ = std::get<int>(version[1]);
 
     if (major_ != DATABASE_MAJOR_VERSION)
     {
@@ -62,7 +62,7 @@ namespace verbly {
 
     for (hatkirby::row& r : rows)
     {
-      result.emplace(std::move(mpark::get<std::string>(r[0])));
+      result.emplace(std::move(std::get<std::string>(r[0])));
     }
 
     return result;
@@ -79,7 +79,7 @@ namespace verbly {
 
     for (hatkirby::row& r : rows)
     {
-      result.emplace(std::move(mpark::get<std::string>(r[0])));
+      result.emplace(std::move(std::get<std::string>(r[0])));
     }
 
     return result;
diff --git a/lib/filter.cpp b/lib/filter.cpp
index 592b190..e3174ce 100644
--- a/lib/filter.cpp
+++ b/lib/filter.cpp
@@ -377,7 +377,7 @@ namespace verbly {
       throw std::domain_error("This filter does not have a field");
     }
 
-    return mpark::get<singleton_type>(variant_).filterField;
+    return std::get<singleton_type>(variant_).filterField;
   }
 
   filter::comparison filter::getComparison() const
@@ -387,7 +387,7 @@ namespace verbly {
       throw std::domain_error("This filter does not have a comparison");
     }
 
-    return mpark::get<singleton_type>(variant_).filterType;
+    return std::get<singleton_type>(variant_).filterType;
   }
 
   filter filter::getJoinCondition() const
@@ -397,7 +397,7 @@ namespace verbly {
       throw std::domain_error("This filter does not have a join condition");
     }
 
-    const singleton_type& ss = mpark::get<singleton_type>(variant_);
+    const singleton_type& ss = std::get<singleton_type>(variant_);
 
     switch (ss.filterType)
     {
@@ -406,7 +406,7 @@ namespace verbly {
       case comparison::hierarchally_matches:
       case comparison::does_not_hierarchally_match:
       {
-        return *mpark::get<rec_filter>(ss.data);
+        return *std::get<rec_filter>(ss.data);
       }
 
       case comparison::string_equals:
@@ -437,7 +437,7 @@ namespace verbly {
       throw std::domain_error("This filter does not have a string argument");
     }
 
-    const singleton_type& ss = mpark::get<singleton_type>(variant_);
+    const singleton_type& ss = std::get<singleton_type>(variant_);
 
     switch (ss.filterType)
     {
@@ -446,7 +446,7 @@ namespace verbly {
       case comparison::string_is_like:
       case comparison::string_is_not_like:
       {
-        return mpark::get<std::string>(ss.data);
+        return std::get<std::string>(ss.data);
       }
 
       case comparison::int_equals:
@@ -477,7 +477,7 @@ namespace verbly {
       throw std::domain_error("This filter does not have an integer argument");
     }
 
-    const singleton_type& ss = mpark::get<singleton_type>(variant_);
+    const singleton_type& ss = std::get<singleton_type>(variant_);
 
     switch (ss.filterType)
     {
@@ -488,7 +488,7 @@ namespace verbly {
       case comparison::int_is_at_most:
       case comparison::int_is_less_than:
       {
-        return mpark::get<int>(ss.data);
+        return std::get<int>(ss.data);
       }
 
       case comparison::string_equals:
@@ -514,13 +514,13 @@ namespace verbly {
   bool filter::getBooleanArgument() const
   {
     if ((type_ != type::singleton) ||
-      (mpark::get<singleton_type>(variant_).filterType !=
+      (std::get<singleton_type>(variant_).filterType !=
         comparison::boolean_equals))
     {
       throw std::domain_error("This filter does not have a boolean argument");
     }
 
-    return mpark::get<bool>(mpark::get<singleton_type>(variant_).data);
+    return std::get<bool>(std::get<singleton_type>(variant_).data);
   }
 
   field filter::getCompareField() const
@@ -530,14 +530,14 @@ namespace verbly {
       throw std::domain_error("This filter does not have a compare field");
     }
 
-    const singleton_type& ss = mpark::get<singleton_type>(variant_);
+    const singleton_type& ss = std::get<singleton_type>(variant_);
 
     switch (ss.filterType)
     {
       case comparison::field_equals:
       case comparison::field_does_not_equal:
       {
-        return mpark::get<field>(ss.data);
+        return std::get<field>(ss.data);
 
         break;
       }
@@ -579,7 +579,7 @@ namespace verbly {
       throw std::domain_error("This filter is not a group filter");
     }
 
-    return mpark::get<group_type>(variant_).orlogic;
+    return std::get<group_type>(variant_).orlogic;
   }
 
   filter filter::operator+(filter condition) const
@@ -597,7 +597,7 @@ namespace verbly {
       throw std::domain_error("Children can only be added to group filters");
     }
 
-    mpark::get<group_type>(variant_).children.push_back(std::move(condition));
+    std::get<group_type>(variant_).children.push_back(std::move(condition));
 
     return *this;
   }
@@ -609,7 +609,7 @@ namespace verbly {
       throw std::domain_error("This filter has no children");
     }
 
-    return std::begin(mpark::get<group_type>(variant_).children);
+    return std::begin(std::get<group_type>(variant_).children);
   }
 
   filter::const_iterator filter::end() const
@@ -619,7 +619,7 @@ namespace verbly {
       throw std::domain_error("This filter has no children");
     }
 
-    return std::end(mpark::get<group_type>(variant_).children);
+    return std::end(std::get<group_type>(variant_).children);
   }
 
   filter::filter(
@@ -642,7 +642,7 @@ namespace verbly {
       throw std::domain_error("This filter is not a mask filter");
     }
 
-    return mpark::get<mask_type>(variant_).name;
+    return std::get<mask_type>(variant_).name;
   }
 
   bool filter::isMaskInternal() const
@@ -652,7 +652,7 @@ namespace verbly {
       throw std::domain_error("This filter is not a mask filter");
     }
 
-    return mpark::get<mask_type>(variant_).internal;
+    return std::get<mask_type>(variant_).internal;
   }
 
   const filter& filter::getMaskFilter() const
@@ -662,7 +662,7 @@ namespace verbly {
       throw std::domain_error("This filter is not a mask filter");
     }
 
-    return *mpark::get<mask_type>(variant_).subfilter;
+    return *std::get<mask_type>(variant_).subfilter;
   }
 
   filter filter::operator!() const
@@ -676,7 +676,7 @@ namespace verbly {
 
       case type::singleton:
       {
-        const singleton_type& ss = mpark::get<singleton_type>(variant_);
+        const singleton_type& ss = std::get<singleton_type>(variant_);
 
         switch (ss.filterType)
         {
@@ -685,7 +685,7 @@ namespace verbly {
             return filter(
               ss.filterField,
               comparison::int_does_not_equal,
-              mpark::get<int>(ss.data));
+              std::get<int>(ss.data));
           }
 
           case comparison::int_does_not_equal:
@@ -693,7 +693,7 @@ namespace verbly {
             return filter(
               ss.filterField,
               comparison::int_equals,
-              mpark::get<int>(ss.data));
+              std::get<int>(ss.data));
           }
 
           case comparison::int_is_at_least:
@@ -701,7 +701,7 @@ namespace verbly {
             return filter(
               ss.filterField,
               comparison::int_is_less_than,
-              mpark::get<int>(ss.data));
+              std::get<int>(ss.data));
           }
 
           case comparison::int_is_greater_than:
@@ -709,7 +709,7 @@ namespace verbly {
             return filter(
               ss.filterField,
               comparison::int_is_at_most,
-              mpark::get<int>(ss.data));
+              std::get<int>(ss.data));
           }
 
           case comparison::int_is_at_most:
@@ -717,7 +717,7 @@ namespace verbly {
             return filter(
               ss.filterField,
               comparison::int_is_greater_than,
-              mpark::get<int>(ss.data));
+              std::get<int>(ss.data));
           }
 
           case comparison::int_is_less_than:
@@ -725,7 +725,7 @@ namespace verbly {
             return filter(
               ss.filterField,
               comparison::int_is_at_least,
-              mpark::get<int>(ss.data));
+              std::get<int>(ss.data));
           }
 
           case comparison::boolean_equals:
@@ -733,7 +733,7 @@ namespace verbly {
             return filter(
               ss.filterField,
               comparison::boolean_equals,
-              !mpark::get<int>(ss.data));
+              !std::get<int>(ss.data));
           }
 
           case comparison::string_equals:
@@ -741,7 +741,7 @@ namespace verbly {
             return filter(
               ss.filterField,
               comparison::string_does_not_equal,
-              mpark::get<std::string>(ss.data));
+              std::get<std::string>(ss.data));
           }
 
           case comparison::string_does_not_equal:
@@ -749,7 +749,7 @@ namespace verbly {
             return filter(
               ss.filterField,
               comparison::string_equals,
-              mpark::get<std::string>(ss.data));
+              std::get<std::string>(ss.data));
           }
 
           case comparison::string_is_like:
@@ -757,7 +757,7 @@ namespace verbly {
             return filter(
               ss.filterField,
               comparison::string_is_not_like,
-              mpark::get<std::string>(ss.data));
+              std::get<std::string>(ss.data));
           }
 
           case comparison::string_is_not_like:
@@ -765,7 +765,7 @@ namespace verbly {
             return filter(
               ss.filterField,
               comparison::string_is_like,
-              mpark::get<std::string>(ss.data));
+              std::get<std::string>(ss.data));
           }
 
           case comparison::is_null:
@@ -787,7 +787,7 @@ namespace verbly {
             return filter(
               ss.filterField,
               comparison::does_not_match,
-              *mpark::get<rec_filter>(ss.data));
+              *std::get<rec_filter>(ss.data));
           }
 
           case comparison::does_not_match:
@@ -795,7 +795,7 @@ namespace verbly {
             return filter(
               ss.filterField,
               comparison::matches,
-              *mpark::get<rec_filter>(ss.data));
+              *std::get<rec_filter>(ss.data));
           }
 
           case comparison::hierarchally_matches:
@@ -803,7 +803,7 @@ namespace verbly {
             return filter(
               ss.filterField,
               comparison::does_not_hierarchally_match,
-              *mpark::get<rec_filter>(ss.data));
+              *std::get<rec_filter>(ss.data));
           }
 
           case comparison::does_not_hierarchally_match:
@@ -811,7 +811,7 @@ namespace verbly {
             return filter(
               ss.filterField,
               comparison::hierarchally_matches,
-              *mpark::get<rec_filter>(ss.data));
+              *std::get<rec_filter>(ss.data));
           }
 
           case comparison::field_equals:
@@ -819,7 +819,7 @@ namespace verbly {
             return filter(
               ss.filterField,
               comparison::field_does_not_equal,
-              mpark::get<field>(ss.data));
+              std::get<field>(ss.data));
           }
 
           case comparison::field_does_not_equal:
@@ -827,14 +827,14 @@ namespace verbly {
             return filter(
               ss.filterField,
               comparison::field_equals,
-              mpark::get<field>(ss.data));
+              std::get<field>(ss.data));
           }
         }
       }
 
       case type::group:
       {
-        const group_type& gg = mpark::get<group_type>(variant_);
+        const group_type& gg = std::get<group_type>(variant_);
 
         filter result(!gg.orlogic);
 
@@ -848,7 +848,7 @@ namespace verbly {
 
       case type::mask:
       {
-        const mask_type& mm = mpark::get<mask_type>(variant_);
+        const mask_type& mm = std::get<mask_type>(variant_);
 
         return {mm.name, mm.internal, !*mm.subfilter};
       }
@@ -879,7 +879,7 @@ namespace verbly {
       {
         filter result(false);
 
-        group_type& gg = mpark::get<group_type>(result.variant_);
+        group_type& gg = std::get<group_type>(result.variant_);
 
         gg.children.push_back(*this);
         gg.children.push_back(std::move(condition));
@@ -889,13 +889,13 @@ namespace verbly {
 
       case type::group:
       {
-        const group_type& og = mpark::get<group_type>(variant_);
+        const group_type& og = std::get<group_type>(variant_);
 
         if (og.orlogic)
         {
           filter result(false);
 
-          group_type& gg = mpark::get<group_type>(result.variant_);
+          group_type& gg = std::get<group_type>(result.variant_);
 
           gg.children.push_back(*this);
           gg.children.push_back(std::move(condition));
@@ -904,7 +904,7 @@ namespace verbly {
         } else {
           filter result(*this);
 
-          group_type& gg = mpark::get<group_type>(result.variant_);
+          group_type& gg = std::get<group_type>(result.variant_);
 
           gg.children.push_back(std::move(condition));
 
@@ -928,7 +928,7 @@ namespace verbly {
       {
         filter result(true);
 
-        group_type& gg = mpark::get<group_type>(result.variant_);
+        group_type& gg = std::get<group_type>(result.variant_);
 
         gg.children.push_back(*this);
         gg.children.push_back(std::move(condition));
@@ -938,13 +938,13 @@ namespace verbly {
 
       case type::group:
       {
-        const group_type& og = mpark::get<group_type>(variant_);
+        const group_type& og = std::get<group_type>(variant_);
 
         if (!og.orlogic)
         {
           filter result(true);
 
-          group_type& gg = mpark::get<group_type>(result.variant_);
+          group_type& gg = std::get<group_type>(result.variant_);
 
           gg.children.push_back(*this);
           gg.children.push_back(std::move(condition));
@@ -953,7 +953,7 @@ namespace verbly {
         } else {
           filter result(*this);
 
-          group_type& gg = mpark::get<group_type>(result.variant_);
+          group_type& gg = std::get<group_type>(result.variant_);
 
           gg.children.push_back(std::move(condition));
 
@@ -980,7 +980,7 @@ namespace verbly {
 
         case type::singleton:
         {
-          const singleton_type& ss = mpark::get<singleton_type>(variant_);
+          const singleton_type& ss = std::get<singleton_type>(variant_);
 
           // First, switch on the normalized context, and then switch on the
           // current context. We recursively recontextualize by using the
@@ -1147,7 +1147,7 @@ namespace verbly {
 
         case type::group:
         {
-          const group_type& gg = mpark::get<group_type>(variant_);
+          const group_type& gg = std::get<group_type>(variant_);
 
           filter result(gg.orlogic);
           std::map<field, filter> positiveJoins;
@@ -1166,7 +1166,7 @@ namespace verbly {
               case type::singleton:
               {
                 singleton_type& normSing =
-                  mpark::get<singleton_type>(normalized.variant_);
+                  std::get<singleton_type>(normalized.variant_);
 
                 switch (normalized.getComparison())
                 {
@@ -1178,7 +1178,7 @@ namespace verbly {
                     }
 
                     positiveJoins.at(normalized.getField()) +=
-                      std::move(*mpark::get<rec_filter>(normSing.data));
+                      std::move(*std::get<rec_filter>(normSing.data));
 
                     break;
                   }
@@ -1192,7 +1192,7 @@ namespace verbly {
                     }
 
                     negativeJoins.at(normalized.getField()) +=
-                      std::move(*mpark::get<rec_filter>(normSing.data));
+                      std::move(*std::get<rec_filter>(normSing.data));
 
                     break;
                   }
@@ -1202,7 +1202,7 @@ namespace verbly {
                     if (gg.orlogic)
                     {
                       positiveJoins[normalized.getField()] |=
-                        std::move(*mpark::get<rec_filter>(normSing.data));
+                        std::move(*std::get<rec_filter>(normSing.data));
                     } else {
                       result += std::move(normalized);
                     }
@@ -1215,7 +1215,7 @@ namespace verbly {
                     if (!gg.orlogic)
                     {
                       negativeJoins[normalized.getField()] |=
-                        std::move(*mpark::get<rec_filter>(normSing.data));
+                        std::move(*std::get<rec_filter>(normSing.data));
                     } else {
                       result += std::move(normalized);
                     }
@@ -1259,7 +1259,7 @@ namespace verbly {
               case type::mask:
               {
                 mask_type& normMask =
-                  mpark::get<mask_type>(normalized.variant_);
+                  std::get<mask_type>(normalized.variant_);
 
                 auto maskId =
                   std::tie(
@@ -1310,7 +1310,7 @@ namespace verbly {
 
         case type::mask:
         {
-          const mask_type& mm = mpark::get<mask_type>(variant_);
+          const mask_type& mm = std::get<mask_type>(variant_);
 
           return {
             mm.name,
@@ -1333,7 +1333,7 @@ namespace verbly {
 
       case type::group:
       {
-        const group_type& gg = mpark::get<group_type>(variant_);
+        const group_type& gg = std::get<group_type>(variant_);
 
         filter result(gg.orlogic);
         for (const filter& child : gg.children)
@@ -1345,7 +1345,7 @@ namespace verbly {
           }
         }
 
-        group_type& resGroup = mpark::get<group_type>(result.variant_);
+        group_type& resGroup = std::get<group_type>(result.variant_);
 
         if (resGroup.children.empty())
         {
@@ -1362,7 +1362,7 @@ namespace verbly {
 
       case type::mask:
       {
-        const mask_type& mm = mpark::get<mask_type>(variant_);
+        const mask_type& mm = std::get<mask_type>(variant_);
 
         filter subfilter = mm.subfilter->compact();
 
diff --git a/lib/filter.h b/lib/filter.h
index 7db2773..6da30dd 100644
--- a/lib/filter.h
+++ b/lib/filter.h
@@ -4,7 +4,7 @@
 #include <list>
 #include <string>
 #include <memory>
-#include "../vendor/hkutil/vendor/variant.hpp"
+#include <variant>
 #include "../vendor/hkutil/hkutil/recptr.h"
 #include "field.h"
 #include "enums.h"
@@ -133,8 +133,8 @@ namespace verbly {
       field filterField;
       comparison filterType;
 
-      mpark::variant<
-        mpark::monostate,
+      std::variant<
+        std::monostate,
         rec_filter,
         std::string,
         int,
@@ -154,8 +154,8 @@ namespace verbly {
     };
 
     using variant_type =
-      mpark::variant<
-        mpark::monostate,
+      std::variant<
+        std::monostate,
         singleton_type,
         group_type,
         mask_type>;
diff --git a/lib/form.cpp b/lib/form.cpp
index 4983274..571b1df 100644
--- a/lib/form.cpp
+++ b/lib/form.cpp
@@ -25,11 +25,11 @@ namespace verbly {
 
   form::form(const database& db, hatkirby::row row) : valid_(true)
   {
-    id_ = mpark::get<int>(row[0]);
-    text_ = mpark::get<std::string>(row[1]);
-    complexity_ = mpark::get<int>(row[2]);
-    proper_ = (mpark::get<int>(row[3]) == 1);
-    length_ = mpark::get<int>(row[4]);
+    id_ = std::get<int>(row[0]);
+    text_ = std::get<std::string>(row[1]);
+    complexity_ = std::get<int>(row[2]);
+    proper_ = (std::get<int>(row[3]) == 1);
+    length_ = std::get<int>(row[4]);
 
     pronunciations_ = db.pronunciations(*this, pronunciation::id, -1).all();
   }
diff --git a/lib/frame.cpp b/lib/frame.cpp
index 51d6936..2a07e5f 100644
--- a/lib/frame.cpp
+++ b/lib/frame.cpp
@@ -25,9 +25,9 @@ namespace verbly {
 
   frame::frame(const database& db, hatkirby::row row) : valid_(true)
   {
-    id_ = mpark::get<int>(row[0]);
-    groupId_ = mpark::get<int>(row[1]);
-    length_ = mpark::get<int>(row[2]);
+    id_ = std::get<int>(row[0]);
+    groupId_ = std::get<int>(row[1]);
+    length_ = std::get<int>(row[2]);
 
     parts_ = db.parts(*this, verbly::part::index, -1).all();
   }
diff --git a/lib/notion.cpp b/lib/notion.cpp
index 733c852..94a5194 100644
--- a/lib/notion.cpp
+++ b/lib/notion.cpp
@@ -60,19 +60,19 @@ namespace verbly {
 
   notion::notion(const database& db, hatkirby::row row) : valid_(true)
   {
-    id_ = mpark::get<int>(row[0]);
-    partOfSpeech_ = static_cast<part_of_speech>(mpark::get<int>(row[1]));
+    id_ = std::get<int>(row[0]);
+    partOfSpeech_ = static_cast<part_of_speech>(std::get<int>(row[1]));
 
-    if (!mpark::holds_alternative<std::nullptr_t>(row[2]))
+    if (!std::holds_alternative<std::nullptr_t>(row[2]))
     {
       hasWnid_ = true;
-      wnid_ = mpark::get<int>(row[2]);
+      wnid_ = std::get<int>(row[2]);
     }
 
-    if (!mpark::holds_alternative<std::nullptr_t>(row[3]))
+    if (!std::holds_alternative<std::nullptr_t>(row[3]))
     {
       hasNumOfImages_ = true;
-      numOfImages_ = mpark::get<int>(row[3]);
+      numOfImages_ = std::get<int>(row[3]);
     }
   }
 
diff --git a/lib/part.cpp b/lib/part.cpp
index bd8501a..2f9db87 100644
--- a/lib/part.cpp
+++ b/lib/part.cpp
@@ -76,16 +76,16 @@ namespace verbly {
 
   part::part(const database& db, hatkirby::row row)
   {
-    int id = mpark::get<int>(row[0]);
+    int id = std::get<int>(row[0]);
 
-    type_ = static_cast<part_type>(mpark::get<int>(row[3]));
+    type_ = static_cast<part_type>(std::get<int>(row[3]));
 
     switch (type_)
     {
       case part_type::noun_phrase:
       {
         variant_ = np_type {
-          mpark::get<std::string>(row[4]),
+          std::get<std::string>(row[4]),
           db.selrestrs(id),
           db.synrestrs(id)
         };
@@ -96,7 +96,7 @@ namespace verbly {
       case part_type::preposition:
       {
         hatkirby::blob_type raw =
-          mpark::get<hatkirby::blob_type>(row[5]);
+          std::get<hatkirby::blob_type>(row[5]);
 
         std::string serializedChoices(
           std::begin(raw),
@@ -106,7 +106,7 @@ namespace verbly {
           hatkirby::split<std::vector<std::string>>(
             std::move(serializedChoices),
             ","),
-          (mpark::get<int>(row[6]) == 1)
+          (std::get<int>(row[6]) == 1)
         };
 
         break;
@@ -114,7 +114,7 @@ namespace verbly {
 
       case part_type::literal:
       {
-        variant_ = mpark::get<std::string>(row[7]);
+        variant_ = std::get<std::string>(row[7]);
 
         break;
       }
@@ -136,7 +136,7 @@ namespace verbly {
       throw std::domain_error("part is not a noun phrase");
     }
 
-    return mpark::get<np_type>(variant_).role;
+    return std::get<np_type>(variant_).role;
   }
 
   const std::set<std::string>& part::getNounSelrestrs() const
@@ -146,7 +146,7 @@ namespace verbly {
       throw std::domain_error("part is not a noun phrase");
     }
 
-    return mpark::get<np_type>(variant_).selrestrs;
+    return std::get<np_type>(variant_).selrestrs;
   }
 
   const std::set<std::string>& part::getNounSynrestrs() const
@@ -156,7 +156,7 @@ namespace verbly {
       throw std::domain_error("part is not a noun phrase");
     }
 
-    return mpark::get<np_type>(variant_).synrestrs;
+    return std::get<np_type>(variant_).synrestrs;
   }
 
   bool part::nounHasSynrestr(std::string synrestr) const
@@ -166,7 +166,7 @@ namespace verbly {
       throw std::domain_error("part is not a noun phrase");
     }
 
-    return mpark::get<np_type>(variant_).synrestrs.count(synrestr);
+    return std::get<np_type>(variant_).synrestrs.count(synrestr);
   }
 
   const std::vector<std::string>& part::getPrepositionChoices() const
@@ -176,7 +176,7 @@ namespace verbly {
       throw std::domain_error("part is not a preposition");
     }
 
-    return mpark::get<prep_type>(variant_).choices;
+    return std::get<prep_type>(variant_).choices;
   }
 
   bool part::isPrepositionLiteral() const
@@ -186,7 +186,7 @@ namespace verbly {
       throw std::domain_error("part is not a preposition");
     }
 
-    return mpark::get<prep_type>(variant_).literal;
+    return std::get<prep_type>(variant_).literal;
   }
 
   const std::string& part::getLiteralValue() const
@@ -196,7 +196,7 @@ namespace verbly {
       throw std::domain_error("part is not a literal");
     }
 
-    return mpark::get<std::string>(variant_);
+    return std::get<std::string>(variant_);
   }
 
   filter part::synrestr_field::operator%=(std::string synrestr) const
diff --git a/lib/part.h b/lib/part.h
index 7783a61..a2d3667 100644
--- a/lib/part.h
+++ b/lib/part.h
@@ -6,7 +6,7 @@
 #include <set>
 #include <list>
 #include <hkutil/database.h>
-#include <variant.hpp>
+#include <variant>
 #include "field.h"
 #include "filter.h"
 #include "enums.h"
@@ -129,8 +129,8 @@ namespace verbly {
     };
 
     using variant_type =
-      mpark::variant<
-        mpark::monostate,
+      std::variant<
+        std::monostate,
         np_type,
         prep_type,
         std::string>;
diff --git a/lib/pronunciation.cpp b/lib/pronunciation.cpp
index 3aef815..8da43bd 100644
--- a/lib/pronunciation.cpp
+++ b/lib/pronunciation.cpp
@@ -26,22 +26,22 @@ namespace verbly {
     hatkirby::row row) :
       valid_(true)
   {
-    id_ = mpark::get<int>(row[0]);
+    id_ = std::get<int>(row[0]);
 
     phonemes_ =
       hatkirby::split<std::vector<std::string>>(
-        mpark::get<std::string>(row[1]),
+        std::get<std::string>(row[1]),
         " ");
 
-    syllables_ = mpark::get<int>(row[2]);
-    stress_ = mpark::get<std::string>(row[3]);
+    syllables_ = std::get<int>(row[2]);
+    stress_ = std::get<std::string>(row[3]);
 
-    if (!mpark::holds_alternative<std::nullptr_t>(row[5]))
+    if (!std::holds_alternative<std::nullptr_t>(row[5]))
     {
       hasRhyme_ = true;
 
-      prerhyme_ = mpark::get<std::string>(row[4]);
-      rhyme_ = mpark::get<std::string>(row[5]);
+      prerhyme_ = std::get<std::string>(row[4]);
+      rhyme_ = std::get<std::string>(row[5]);
     }
   }
 
diff --git a/lib/statement.cpp b/lib/statement.cpp
index 669dc2a..3440acb 100644
--- a/lib/statement.cpp
+++ b/lib/statement.cpp
@@ -800,7 +800,7 @@ namespace verbly {
 
       case type::singleton:
       {
-        const singleton_type& singleton = mpark::get<singleton_type>(variant_);
+        const singleton_type& singleton = std::get<singleton_type>(variant_);
 
         sql << singleton.table << "." << singleton.column;
 
@@ -816,20 +816,20 @@ namespace verbly {
               sql << " != ";
             }
 
-            if (mpark::holds_alternative<field_binding>(singleton.value))
+            if (std::holds_alternative<field_binding>(singleton.value))
             {
-              sql << std::get<0>(mpark::get<field_binding>(singleton.value))
+              sql << std::get<0>(std::get<field_binding>(singleton.value))
                 << "."
-                << std::get<1>(mpark::get<field_binding>(singleton.value));
+                << std::get<1>(std::get<field_binding>(singleton.value));
             } else if (debug)
             {
-              if (mpark::holds_alternative<std::string>(singleton.value))
+              if (std::holds_alternative<std::string>(singleton.value))
               {
-                sql << "\"" << mpark::get<std::string>(singleton.value) << "\"";
+                sql << "\"" << std::get<std::string>(singleton.value) << "\"";
               }
-              else if (mpark::holds_alternative<int>(singleton.value))
+              else if (std::holds_alternative<int>(singleton.value))
               {
-                sql << mpark::get<int>(singleton.value);
+                sql << std::get<int>(singleton.value);
               }
             } else {
               sql << "?";
@@ -844,7 +844,7 @@ namespace verbly {
 
             if (debug)
             {
-              sql << mpark::get<int>(singleton.value);
+              sql << std::get<int>(singleton.value);
             } else {
               sql << "?";
             }
@@ -858,7 +858,7 @@ namespace verbly {
 
             if (debug)
             {
-              sql << mpark::get<int>(singleton.value);
+              sql << std::get<int>(singleton.value);
             } else {
               sql << "?";
             }
@@ -872,7 +872,7 @@ namespace verbly {
 
             if (debug)
             {
-              sql << mpark::get<int>(singleton.value);
+              sql << std::get<int>(singleton.value);
             } else {
               sql << "?";
             }
@@ -886,7 +886,7 @@ namespace verbly {
 
             if (debug)
             {
-              sql << mpark::get<int>(singleton.value);
+              sql << std::get<int>(singleton.value);
             } else {
               sql << "?";
             }
@@ -900,7 +900,7 @@ namespace verbly {
 
             if (debug)
             {
-              sql << "\"" << mpark::get<std::string>(singleton.value) << "\"";
+              sql << "\"" << std::get<std::string>(singleton.value) << "\"";
             } else {
               sql << "?";
             }
@@ -914,7 +914,7 @@ namespace verbly {
 
             if (debug)
             {
-              sql << "\"" << mpark::get<std::string>(singleton.value) << "\"";
+              sql << "\"" << std::get<std::string>(singleton.value) << "\"";
             } else {
               sql << "?";
             }
@@ -942,7 +942,7 @@ namespace verbly {
 
       case type::group:
       {
-        const group_type& group = mpark::get<group_type>(variant_);
+        const group_type& group = std::get<group_type>(variant_);
 
         std::list<std::string> clauses;
         for (const condition& cond : group.children)
@@ -990,14 +990,14 @@ namespace verbly {
 
       case type::singleton:
       {
-        const singleton_type& singleton = mpark::get<singleton_type>(variant_);
+        const singleton_type& singleton = std::get<singleton_type>(variant_);
 
-        if (mpark::holds_alternative<std::string>(singleton.value))
+        if (std::holds_alternative<std::string>(singleton.value))
         {
-          return {{ mpark::get<std::string>(singleton.value) }};
-        } else if (mpark::holds_alternative<int>(singleton.value))
+          return {{ std::get<std::string>(singleton.value) }};
+        } else if (std::holds_alternative<int>(singleton.value))
         {
-          return {{ mpark::get<int>(singleton.value) }};
+          return {{ std::get<int>(singleton.value) }};
         } else {
           return {};
         }
@@ -1005,7 +1005,7 @@ namespace verbly {
 
       case type::group:
       {
-        const group_type& group = mpark::get<group_type>(variant_);
+        const group_type& group = std::get<group_type>(variant_);
 
         std::list<hatkirby::binding> bindings;
         for (const condition& cond : group.children)
@@ -1035,7 +1035,7 @@ namespace verbly {
       throw std::domain_error("Cannot add condition to non-group condition");
     }
 
-    group_type& group = mpark::get<group_type>(variant_);
+    group_type& group = std::get<group_type>(variant_);
     group.children.emplace_back(std::move(n));
 
     return *this;
@@ -1082,7 +1082,7 @@ namespace verbly {
       throw std::domain_error("Cannot get children of non-group condition");
     }
 
-    const group_type& group = mpark::get<group_type>(variant_);
+    const group_type& group = std::get<group_type>(variant_);
 
     return group.children;
   }
@@ -1099,7 +1099,7 @@ namespace verbly {
 
       case type::group:
       {
-        const group_type& group = mpark::get<group_type>(variant_);
+        const group_type& group = std::get<group_type>(variant_);
 
         condition result(group.orlogic);
 
@@ -1110,7 +1110,7 @@ namespace verbly {
           if (newChild.type_ == type::group)
           {
             group_type& childGroup =
-              mpark::get<group_type>(newChild.variant_);
+              std::get<group_type>(newChild.variant_);
 
             if (childGroup.orlogic == group.orlogic)
             {
@@ -1144,7 +1144,7 @@ namespace verbly {
 
       case type::singleton:
       {
-        const singleton_type& singleton = mpark::get<singleton_type>(variant_);
+        const singleton_type& singleton = std::get<singleton_type>(variant_);
 
         if (singleton.parentObject != object::undefined &&
             singleton.parentObject == context)
@@ -1155,7 +1155,7 @@ namespace verbly {
             singleton.comparison,
             field_binding {
               tableName,
-              std::get<1>(mpark::get<field_binding>(singleton.value))
+              std::get<1>(std::get<field_binding>(singleton.value))
             }
           };
         } else {
@@ -1165,7 +1165,7 @@ namespace verbly {
 
       case type::group:
       {
-        const group_type& group = mpark::get<group_type>(variant_);
+        const group_type& group = std::get<group_type>(variant_);
 
         condition result(group.orlogic);
         for (const condition& cond : group.children)
diff --git a/lib/statement.h b/lib/statement.h
index 6c2e42e..632807f 100644
--- a/lib/statement.h
+++ b/lib/statement.h
@@ -5,7 +5,7 @@
 #include <list>
 #include <map>
 #include <hkutil/database.h>
-#include <variant.hpp>
+#include <variant>
 #include "enums.h"
 #include "field.h"
 #include "filter.h"
@@ -19,8 +19,8 @@ namespace verbly {
     std::tuple<std::string, std::string>;
 
   using binding =
-    mpark::variant<
-      mpark::monostate,
+    std::variant<
+      std::monostate,
       std::string,
       int,
       field_binding>;
@@ -185,8 +185,8 @@ namespace verbly {
       };
 
       using variant_type =
-        mpark::variant<
-          mpark::monostate,
+        std::variant<
+          std::monostate,
           singleton_type,
           group_type>;
 
diff --git a/lib/token.cpp b/lib/token.cpp
index b3c7062..6b78f53 100644
--- a/lib/token.cpp
+++ b/lib/token.cpp
@@ -23,7 +23,7 @@ namespace verbly {
 
       case type::utterance:
       {
-        const utterance_type& utterance = mpark::get<utterance_type>(variant_);
+        const utterance_type& utterance = std::get<utterance_type>(variant_);
 
         return std::all_of(
           std::begin(utterance),
@@ -35,7 +35,7 @@ namespace verbly {
 
       case type::transform:
       {
-        const transform_type& transform = mpark::get<transform_type>(variant_);
+        const transform_type& transform = std::get<transform_type>(variant_);
 
         return transform.inner->isComplete();
       }
@@ -56,7 +56,7 @@ namespace verbly {
     {
       case type::word:
       {
-        const word_type& w = mpark::get<word_type>(variant_);
+        const word_type& w = std::get<word_type>(variant_);
 
         const form& wordForm = w.value.getInflections(w.category).front();
 
@@ -108,7 +108,7 @@ namespace verbly {
 
       case type::literal:
       {
-        std::string result = mpark::get<literal_type>(variant_);
+        std::string result = std::get<literal_type>(variant_);
 
         if (indefiniteArticle && std::isalpha(result[0]))
         {
@@ -164,7 +164,7 @@ namespace verbly {
 
       case type::utterance:
       {
-        const utterance_type& utterance = mpark::get<utterance_type>(variant_);
+        const utterance_type& utterance = std::get<utterance_type>(variant_);
 
         bool first = true;
         std::list<std::string> compiled;
@@ -192,7 +192,7 @@ namespace verbly {
 
       case type::transform:
       {
-        const transform_type& transform = mpark::get<transform_type>(variant_);
+        const transform_type& transform = std::get<transform_type>(variant_);
 
         switch (transform.type)
         {
@@ -257,7 +257,7 @@ namespace verbly {
       throw std::domain_error("Token is not a word");
     }
 
-    return mpark::get<word_type>(variant_).value;
+    return std::get<word_type>(variant_).value;
   }
 
   token token::inflect(inflection category) const
@@ -268,7 +268,7 @@ namespace verbly {
     }
 
     return {
-      mpark::get<word_type>(variant_).value,
+      std::get<word_type>(variant_).value,
       category
     };
   }
@@ -293,7 +293,7 @@ namespace verbly {
       throw std::domain_error("Token is not a literal");
     }
 
-    return mpark::get<literal_type>(variant_);
+    return std::get<literal_type>(variant_);
   }
 
   token::token(
@@ -310,7 +310,7 @@ namespace verbly {
       throw std::domain_error("Token is not a part");
     }
 
-    return mpark::get<part>(variant_);
+    return std::get<part>(variant_);
   }
 
   token::token(
@@ -327,7 +327,7 @@ namespace verbly {
       throw std::domain_error("Token is not a fillin");
     }
 
-    return mpark::get<fillin_type>(variant_);
+    return std::get<fillin_type>(variant_);
   }
 
   bool token::hasSynrestr(std::string synrestr) const
@@ -337,7 +337,7 @@ namespace verbly {
       throw std::domain_error("Token is not a fillin");
     }
 
-    return mpark::get<fillin_type>(variant_).count(synrestr);
+    return std::get<fillin_type>(variant_).count(synrestr);
   }
 
   void token::addSynrestr(std::string synrestr)
@@ -347,7 +347,7 @@ namespace verbly {
       throw std::domain_error("Token is not a fillin");
     }
 
-    fillin_type& fillin = mpark::get<fillin_type>(variant_);
+    fillin_type& fillin = std::get<fillin_type>(variant_);
     fillin.insert(std::move(synrestr));
   }
 
@@ -378,7 +378,7 @@ namespace verbly {
       throw std::domain_error("Token is not an utterance");
     }
 
-    return std::begin(mpark::get<utterance_type>(variant_));
+    return std::begin(std::get<utterance_type>(variant_));
   }
 
   token::const_iterator token::begin() const
@@ -388,7 +388,7 @@ namespace verbly {
       throw std::domain_error("Token is not an utterance");
     }
 
-    return std::begin(mpark::get<utterance_type>(variant_));
+    return std::begin(std::get<utterance_type>(variant_));
   }
 
   token::iterator token::end()
@@ -398,7 +398,7 @@ namespace verbly {
       throw std::domain_error("Token is not an utterance");
     }
 
-    return std::end(mpark::get<utterance_type>(variant_));
+    return std::end(std::get<utterance_type>(variant_));
   }
 
   token::const_iterator token::end() const
@@ -408,7 +408,7 @@ namespace verbly {
       throw std::domain_error("Token is not an utterance");
     }
 
-    return std::end(mpark::get<utterance_type>(variant_));
+    return std::end(std::get<utterance_type>(variant_));
   }
 
   token& token::operator<<(token arg)
@@ -418,7 +418,7 @@ namespace verbly {
       throw std::domain_error("Token is not an utterance");
     }
 
-    utterance_type& utterance = mpark::get<utterance_type>(variant_);
+    utterance_type& utterance = std::get<utterance_type>(variant_);
     utterance.push_back(std::move(arg));
 
     return *this;
@@ -460,7 +460,7 @@ namespace verbly {
       throw std::domain_error("Invalid access on non-tranform token");
     }
 
-    return *mpark::get<transform_type>(variant_).inner;
+    return *std::get<transform_type>(variant_).inner;
   }
 
   const token& token::getInnerToken() const
@@ -470,7 +470,7 @@ namespace verbly {
       throw std::domain_error("Invalid access on non-tranform token");
     }
 
-    return *mpark::get<transform_type>(variant_).inner;
+    return *std::get<transform_type>(variant_).inner;
   }
 
   token::token(
diff --git a/lib/token.h b/lib/token.h
index 910a465..a18fe42 100644
--- a/lib/token.h
+++ b/lib/token.h
@@ -5,7 +5,7 @@
 #include <string>
 #include <list>
 #include <set>
-#include <variant.hpp>
+#include <variant>
 #include <hkutil/recptr.h>
 #include "enums.h"
 #include "word.h"
@@ -38,7 +38,7 @@ namespace verbly {
       bool isEmpty() const
       {
         return (type_ == type::utterance &&
-          mpark::get<utterance_type>(variant_).empty());
+          std::get<utterance_type>(variant_).empty());
       }
 
       // Word
@@ -153,7 +153,7 @@ namespace verbly {
       };
 
       using variant_type =
-        mpark::variant<
+        std::variant<
           word_type,
           literal_type,
           part,
diff --git a/lib/word.cpp b/lib/word.cpp
index 2fccb9f..5df9ba1 100644
--- a/lib/word.cpp
+++ b/lib/word.cpp
@@ -46,22 +46,22 @@ namespace verbly {
 
   word::word(const database& db, hatkirby::row row) : db_(&db), valid_(true)
   {
-    id_ = mpark::get<int>(row[0]);
+    id_ = std::get<int>(row[0]);
 
-    notion_ = db.notions(notion::id == mpark::get<int>(row[1])).first();
+    notion_ = db.notions(notion::id == std::get<int>(row[1])).first();
 
-    if (!mpark::holds_alternative<std::nullptr_t>(row[3]))
+    if (!std::holds_alternative<std::nullptr_t>(row[3]))
     {
       hasTagCount_ = true;
-      tagCount_ = mpark::get<int>(row[3]);
+      tagCount_ = std::get<int>(row[3]);
     }
 
-    if (!mpark::holds_alternative<std::nullptr_t>(row[4]))
+    if (!std::holds_alternative<std::nullptr_t>(row[4]))
     {
-      adjectivePosition_ = static_cast<positioning>(mpark::get<int>(row[4]));
+      adjectivePosition_ = static_cast<positioning>(std::get<int>(row[4]));
     }
 
-    if (!mpark::holds_alternative<std::nullptr_t>(row[5]))
+    if (!std::holds_alternative<std::nullptr_t>(row[5]))
     {
       frames_ = db.frames(*this).all();
     }
diff --git a/vendor/hkutil b/vendor/hkutil
index a9a5996..fdddefb 160000
--- a/vendor/hkutil
+++ b/vendor/hkutil
@@ -1 +1 @@
-Subproject commit a9a5996310bb33207d3338f353aab97b9ed3a5e8
+Subproject commit fdddefbbbb8f3c0bd223280c74fa7e05bfdc3521
-- 
cgit 1.4.1