From 385baad3a860d75d47f13e27ee173c796e4407bf Mon Sep 17 00:00:00 2001 From: Grady O'Connell Date: Mon, 13 Aug 2018 05:11:55 -0700 Subject: [PATCH 01/10] use meta::make, mutexed::with(), clean examples premake --- kit/async/mx.h | 2 +- kit/factory/factory.h | 8 +-- kit/kit.h | 5 ++ kit/meta/meta.h | 7 ++ premake5.lua | 6 -- tests/meta.test.cpp | 52 +++++++------- toys/premake4.lua | 156 +++++++++++------------------------------- 7 files changed, 82 insertions(+), 154 deletions(-) diff --git a/kit/async/mx.h b/kit/async/mx.h index 81aca96..fe53722 100644 --- a/kit/async/mx.h +++ b/kit/async/mx.h @@ -226,7 +226,7 @@ class Multiplexer: //std::shared_ptr> channel( // std::function>)> worker //) { - // auto chan = boost::make_local_shared>(); + // auto chan = boost::make_shared>(); // // ... inside lambda if(chan->closed()) remove? //} diff --git a/kit/factory/factory.h b/kit/factory/factory.h index 89e51f3..baa541c 100644 --- a/kit/factory/factory.h +++ b/kit/factory/factory.h @@ -76,10 +76,10 @@ class Factory: } void config(typename TMeta::ptr cfg) {m_pConfig=cfg;} void config(std::string cfg) {m_pConfig=kit::make(cfg);} - void with(std::function cb){ - auto l = this->lock(); - cb(); - } + //void with(std::function cb){ + // auto l = this->lock(); + // cb(); + //} virtual ~Factory() {} diff --git a/kit/kit.h b/kit/kit.h index 7e5eea9..38d051a 100644 --- a/kit/kit.h +++ b/kit/kit.h @@ -259,6 +259,11 @@ namespace kit Lock lock(Strategy strategy) const { return Lock(m_Mutex, strategy); } + template + void with(Func cb){ + auto l = lock(); + cb(); + } //template, class DeferStrategy> //std::optional try_lock() { diff --git a/kit/meta/meta.h b/kit/meta/meta.h index e92346c..3687e8c 100644 --- a/kit/meta/meta.h +++ b/kit/meta/meta.h @@ -277,13 +277,20 @@ class Meta_: public: using mutex_type = Mutex; + //typedef Ptr> ptr; + //typedef Ptr> cptr; using ptr = Ptr>; using cptr = Ptr>; + //template + //static ptr make(Args&&... args){ + // return kit::make(std::forward(args)...); + //} template static ptr make(Args&&... args){ return kit::make(std::forward(args)...); } + friend struct MetaElement; diff --git a/premake5.lua b/premake5.lua index 7b25ba4..625f897 100644 --- a/premake5.lua +++ b/premake5.lua @@ -47,7 +47,6 @@ workspace("kit") } includedirs { "/usr/local/include/", - "/usr/include/bullet/", "/usr/include/rapidxml/", "/usr/include/raknet/DependentExtensions" } @@ -135,13 +134,8 @@ workspace("kit") -- Exluding Files excludes { - } includedirs { - "lib/local_shared_ptr/", - "/usr/local/include/", - "/usr/include/bullet/", - "/usr/include/raknet/DependentExtensions" } diff --git a/tests/meta.test.cpp b/tests/meta.test.cpp index b7bc60d..913e35a 100644 --- a/tests/meta.test.cpp +++ b/tests/meta.test.cpp @@ -10,7 +10,7 @@ using kit::local_shared_ptr; TEST_CASE("Meta","[meta]") { SECTION("empty") { - auto m = make_local_shared(); + auto m = Meta::make(); REQUIRE(m); REQUIRE(!*m); REQUIRE(m->empty()); @@ -18,7 +18,7 @@ TEST_CASE("Meta","[meta]") { } SECTION("set") { - auto m = make_local_shared(); + auto m = Meta::make(); m->set("one", 1); REQUIRE(*m); @@ -41,16 +41,16 @@ TEST_CASE("Meta","[meta]") { } SECTION("add") { - auto m = make_local_shared(); + auto m = Meta::make(); - REQUIRE(m->add(make_local_shared()) == 0); - REQUIRE(m->add(make_local_shared()) == 1); + REQUIRE(m->add(Meta::make()) == 0); + REQUIRE(m->add(Meta::make()) == 1); REQUIRE(m->size() == 2); REQUIRE(m->key_count() == 0); } SECTION("ensure") { - auto m = make_local_shared(); + auto m = Meta::make(); REQUIRE(m->ensure("a", 1) == 1); REQUIRE(m->ensure("b", 2) == 2); @@ -65,7 +65,7 @@ TEST_CASE("Meta","[meta]") { SECTION("remove") { SECTION("at index") { - auto m = make_local_shared(); + auto m = Meta::make(); m->add(1); m->add(2); // index 1 m->add(3); @@ -85,7 +85,7 @@ TEST_CASE("Meta","[meta]") { SECTION("pop") { SECTION("front") { - auto m = make_local_shared(); + auto m = Meta::make(); m->add(1); m->add(2); m->pop_front(); @@ -96,7 +96,7 @@ TEST_CASE("Meta","[meta]") { REQUIRE_THROWS_AS(m->pop_front(), std::out_of_range); } SECTION("back") { - auto m = make_local_shared(); + auto m = Meta::make(); m->add(1); m->add(2); m->pop_back(); @@ -109,7 +109,7 @@ TEST_CASE("Meta","[meta]") { } SECTION("by key") { - auto m = make_local_shared(); + auto m = Meta::make(); m->set("one" ,1); m->set("two", 2); m->set("three", 3); @@ -131,7 +131,7 @@ TEST_CASE("Meta","[meta]") { SECTION("types") { { - auto m = make_local_shared(); + auto m = Meta::make(); m->set("nullptr", nullptr); m->set("nullmeta", local_shared_ptr()); //REQUIRE(not m->at("nullptr")); @@ -144,7 +144,7 @@ TEST_CASE("Meta","[meta]") { //} SECTION("clear") { - auto m = make_local_shared(); + auto m = Meta::make(); m->set("one",1); m->set("two","2"); @@ -156,10 +156,10 @@ TEST_CASE("Meta","[meta]") { } SECTION("at") { - auto m = make_local_shared(); + auto m = Meta::make(); m->set("one", 1); m->set("two", "2"); - m->add(make_local_shared()); + m->add(Meta::make()); REQUIRE(m->at("one") == 1); REQUIRE(m->at(0) == 1); @@ -169,10 +169,10 @@ TEST_CASE("Meta","[meta]") { } SECTION("parent") { - auto m = make_local_shared(); + auto m = Meta::make(); REQUIRE(!m->parent()); REQUIRE(m->root() == m); - auto c1 = make_local_shared(); + auto c1 = Meta::make(); m->add(c1); REQUIRE(c1->parent() == m); } @@ -180,7 +180,7 @@ TEST_CASE("Meta","[meta]") { SECTION("iterate") { SECTION("map") { string json = "{\"one\":1,\"two\":2,\"three\": 3}"; - auto m = make_local_shared(MetaFormat::JSON, json); + auto m = Meta::make(MetaFormat::JSON, json); int i = 0; m->each_c([&]( local_shared_ptr parent, @@ -218,14 +218,14 @@ TEST_CASE("Meta","[meta]") { SECTION("serialization") { SECTION("objects") { - auto m = make_local_shared(MetaFormat::JSON,"{\"one\":1}"); + auto m = Meta::make(MetaFormat::JSON,"{\"one\":1}"); REQUIRE(!m->empty()); REQUIRE(m->at("one") == 1); REQUIRE(!m->empty()); m->clear(); REQUIRE(m->empty()); - m = make_local_shared(); + m = Meta::make(); m->deserialize(MetaFormat::JSON,"{\"one\":1}"); REQUIRE(m->at("one") == 1); @@ -237,7 +237,7 @@ TEST_CASE("Meta","[meta]") { REQUIRE(not m->empty()); REQUIRE(m->at("one") == 1); - m->set("test", make_local_shared()); + m->set("test", Meta::make()); m->meta("test")->set("two", 2); data = m->serialize(MetaFormat::INI); m->clear(); @@ -256,7 +256,7 @@ TEST_CASE("Meta","[meta]") { } SECTION("arrays") { - auto m = make_local_shared(MetaFormat::JSON,"{\"numbers\":[1,2,3]}"); + auto m = Meta::make(MetaFormat::JSON,"{\"numbers\":[1,2,3]}"); auto a = m->at>(0); REQUIRE(a); REQUIRE(a->size() == 3); @@ -265,7 +265,7 @@ TEST_CASE("Meta","[meta]") { REQUIRE(a->at(2) == 3); // strings - m = make_local_shared(MetaFormat::JSON,"{ \"a\": [\"b\",\"c\"] }"); + m = Meta::make(MetaFormat::JSON,"{ \"a\": [\"b\",\"c\"] }"); a = m->at>(0); REQUIRE(a); REQUIRE(a->size() == 2); @@ -273,7 +273,7 @@ TEST_CASE("Meta","[meta]") { REQUIRE(a->at(1) == "c"); // nested - m = make_local_shared(MetaFormat::JSON,"{\"numbers\":[[],[[]],[[],[]]]}"); + m = Meta::make(MetaFormat::JSON,"{\"numbers\":[[],[[]],[[],[]]]}"); a = m->at>(0); REQUIRE(a); REQUIRE(a->size() == 3); @@ -291,14 +291,14 @@ TEST_CASE("Meta","[meta]") { { // no deserialize flags - auto m = make_local_shared(MetaFormat::JSON,"{\"one\":1}"); + auto m = Meta::make(MetaFormat::JSON,"{\"one\":1}"); m->deserialize(MetaFormat::JSON,"{\"two\":2}"); REQUIRE(m->size() == 1); // no flags should clear prior data } { // same as above, but with F_MERGE flag - auto m = make_local_shared(MetaFormat::JSON,"{\"one\":1}"); + auto m = Meta::make(MetaFormat::JSON,"{\"one\":1}"); m->deserialize(MetaFormat::JSON,"{\"two\":2}", Meta::F_MERGE // <-- new flag ); @@ -312,7 +312,7 @@ TEST_CASE("Meta","[meta]") { SECTION("correct types") { // make sure doubles with trailing .0 don't serialize as ints - auto m = make_local_shared(MetaFormat::JSON,"{\"one\":1.0}"); + auto m = Meta::make(MetaFormat::JSON,"{\"one\":1.0}"); REQUIRE_THROWS_AS(m->at("one"), boost::bad_any_cast); REQUIRE(floatcmp(m->at("one"), 1.0)); } diff --git a/toys/premake4.lua b/toys/premake4.lua index a9c746d..e42c5a6 100644 --- a/toys/premake4.lua +++ b/toys/premake4.lua @@ -17,129 +17,51 @@ solution("kit") defines { "NDEBUG" } flags { "OptimizeSpeed" } - project("echo") - kind("ConsoleApp") - language("C++") + language("C++") + links { + "pthread", + "boost_thread", + "SDL2", + "boost_system", + "boost_regex", + "boost_filesystem", + "boost_coroutine", + "jsoncpp" + } + defines { "BACKWARD_HAS_BFD=1" } + includedirs { + "../lib/local_shared_ptr", + "../vendor/include/", + "/usr/include/cpp-netlib/" + } + + configuration {"debug"} links { - "pthread", - "boost_thread", - "SDL2", - "boost_system", - "boost_regex", - "boost_filesystem", - "boost_coroutine", - "jsoncpp" - } - files { - "src/echo.cpp", - "../kit/**.cpp", - "../kit/**.inl" + "bfd", + "iberty" } - - defines { "BACKWARD_HAS_BFD=1" } - - includedirs { - "../vendor/include/", - "/usr/include/cpp-netlib/" - } - - configuration {"debug"} - links { - "bfd", - "iberty" - } - linkoptions { "`llvm-config --libs core` `llvm-config --ldflags`" } - configuration {} - - configuration { "gmake" } - --buildoptions { "-std=c++11", "-pedantic", "-Wall", "-Wextra" } - buildoptions { "-std=c++11" } - configuration { "macosx" } - buildoptions { "-U__STRICT_ANSI__", "-stdlib=libc++" } - linkoptions { "-stdlib=libc++" } - configuration {} + linkoptions { "`llvm-config --libs core` `llvm-config --ldflags`" } + configuration {} + + configuration { "gmake" } + --buildoptions { "-std=c++11", "-pedantic", "-Wall", "-Wextra" } + buildoptions { "-std=c++11" } + configuration { "macosx" } + buildoptions { "-U__STRICT_ANSI__", "-stdlib=libc++" } + linkoptions { "-stdlib=libc++" } + configuration {} + + files { "../kit/**.cpp" } + + project("echo") + kind("ConsoleApp") + files { "src/echo.cpp" } project("stability") kind("ConsoleApp") - language("C++") - links { - "pthread", - "boost_thread", - "SDL2", - "boost_system", - "boost_regex", - "boost_filesystem", - "boost_coroutine", - "jsoncpp" - } - files { - "src/stability.cpp", - "../kit/**.cpp", - "../kit/**.inl" - } - - defines { "BACKWARD_HAS_BFD=1" } + files { "src/stability.cpp" } - includedirs { - "../vendor/include/", - "/usr/include/cpp-netlib/" - } - - configuration {"debug"} - links { - "bfd", - "iberty" - } - linkoptions { "`llvm-config --libs core` `llvm-config --ldflags`" } - configuration {} - - configuration { "gmake" } - --buildoptions { "-std=c++11", "-pedantic", "-Wall", "-Wextra" } - buildoptions { "-std=c++11" } - configuration { "macosx" } - buildoptions { "-U__STRICT_ANSI__", "-stdlib=libc++" } - linkoptions { "-stdlib=libc++" } - configuration {} - project("chat") kind("ConsoleApp") - language("C++") - links { - "pthread", - "boost_thread", - "SDL2", - "boost_system", - "boost_regex", - "boost_filesystem", - "boost_coroutine", - "jsoncpp" - } - files { - "src/chat.cpp", - "../kit/**.cpp", - "../kit/**.inl" - } + files { "src/chat.cpp" } - defines { "BACKWARD_HAS_BFD=1" } - - includedirs { - "../vendor/include/", - "/usr/include/cpp-netlib/" - } - - configuration {"debug"} - links { - "bfd", - "iberty" - } - linkoptions { "`llvm-config --libs core` `llvm-config --ldflags`" } - configuration {} - - configuration { "gmake" } - --buildoptions { "-std=c++11", "-pedantic", "-Wall", "-Wextra" } - buildoptions { "-std=c++11" } - configuration { "macosx" } - buildoptions { "-U__STRICT_ANSI__", "-stdlib=libc++" } - linkoptions { "-stdlib=libc++" } - configuration {} - From 8f0d494e31357e04e002461548280d310d87c6e2 Mon Sep 17 00:00:00 2001 From: Grady O'Connell Date: Sat, 2 Feb 2019 03:07:38 -0800 Subject: [PATCH 02/10] fixed lib path, removed broken tribool usage --- kit/kit.h | 17 ++++++++--------- premake5.lua | 1 + 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/kit/kit.h b/kit/kit.h index 38d051a..87639fe 100644 --- a/kit/kit.h +++ b/kit/kit.h @@ -17,7 +17,6 @@ #include #include #include -#include // extended identifiers in msvc (and,or,not) #ifdef _MSC_VER @@ -882,22 +881,22 @@ namespace kit } template - boost::tribool any_eq_type(const boost::any& a, const boost::any& b) { + int any_eq_type(const boost::any& a, const boost::any& b) { if (a.type() == typeid(T) && b.type() == typeid(T)) return boost::any_cast(a) == boost::any_cast(b); - return boost::tribool::indeterminate_value; + return -1; } inline bool any_eq(const boost::any& a, const boost::any& b) { if(a.type() != b.type()) return false; - {auto r = any_eq_type(a,b); if(r||!r) return r;} - {auto r = any_eq_type(a,b); if(r||!r) return r;} - {auto r = any_eq_type(a,b); if(r||!r) return r;} - {auto r = any_eq_type(a,b); if(r||!r) return r;} - {auto r = any_eq_type(a,b); if(r||!r) return r;} - {auto r = any_eq_type(a,b); if(r||!r) return r;} + {auto r = any_eq_type(a,b); if(r>=0) return r; } + {auto r = any_eq_type(a,b); if(r>=0) return r;} + {auto r = any_eq_type(a,b); if(r>=0) return r;} + {auto r = any_eq_type(a,b); if(r>=0) return r;} + {auto r = any_eq_type(a,b); if(r>=0) return r;} + {auto r = any_eq_type(a,b); if(r>=0) return r;} throw std::runtime_error("unable to compare values"); } diff --git a/premake5.lua b/premake5.lua index 625f897..79f0f1d 100644 --- a/premake5.lua +++ b/premake5.lua @@ -137,5 +137,6 @@ workspace("kit") } includedirs { + "lib/local_shared_ptr", } From cd6cabf46b9e1e0811773bffa858a7df2d868db6 Mon Sep 17 00:00:00 2001 From: Grady O'Connell Date: Sat, 2 Mar 2019 20:35:48 -0800 Subject: [PATCH 03/10] changed Freq::Time internal storage type to seconds/float --- kit/freq/freq.h | 45 ++++++++++++++++++++++---------------------- lib/local_shared_ptr | 2 +- 2 files changed, 23 insertions(+), 24 deletions(-) mode change 160000 => 120000 lib/local_shared_ptr diff --git a/kit/freq/freq.h b/kit/freq/freq.h index 71700d1..3a16502 100644 --- a/kit/freq/freq.h +++ b/kit/freq/freq.h @@ -20,42 +20,41 @@ class Freq class Time { public: - unsigned int value; + //unsigned int value; + float sec; Time(): - value(0) {} - explicit Time(unsigned int ms) { - value = ms; - } + sec(0) {} + explicit Time(float ms) { sec = ms/1000.0f; } // deprecated Time(const Time& t) = default; Time& operator=(const Time& t) = default; Time(Time&& t) = default; Time& operator=(Time&& t) = default; - unsigned int internal() const { return value; } + unsigned ui() const { return (unsigned int)(sec*1000.0f); } //static Time seconds(unsigned int s) { return Time(s * 1000);} - static Time seconds(float s) { return Time((unsigned int)(s * 1000.0f)); } + static Time seconds(float s) { return Time(s*1000.0f); } //static Time minutes(unsigned int m) { return Time(m * 60000);} - static Time minutes(float m) { return Time((unsigned int)(m * 60000.0f));} - static Time ms(unsigned int ms) { return Time(ms); } + static Time minutes(float m) { return Time(m * 60000.0f);} + static Time ms(float ms) { return Time(ms); } - //operator bool() const { return value; } - //operator float() const { return value / 1000.0f; } + //operator bool() const { return sec; } + //operator float() const { return sec / 1000.0f; } Time& operator+=(Time t) { - value += t.internal(); + sec += t.sec; return *this; } - bool operator>(Time t) const { return value > t.internal(); } - bool operator<(Time t) const { return value < t.internal(); } - bool operator>=(Time t) const { return value >= t.internal(); } - bool operator<=(Time t) const { return value <= t.internal(); } + bool operator>(Time t) const { return sec > t.sec; } + bool operator<(Time t) const { return sec < t.sec; } + bool operator>=(Time t) const { return sec >= t.sec; } + bool operator<=(Time t) const { return sec <= t.sec; } operator bool() const { - return value; + return std::abs(sec*1000.0f) > K_EPSILON; } - float s() const { return value / 1000.0f; } - float seconds() const { return value / 1000.0f; } - unsigned int ms() const { return value; } + float s() const { return sec; } + float seconds() const { return sec; } + float ms() const { return sec * 1000.0f; } }; class Timeline { @@ -122,7 +121,7 @@ class Freq } bool elapsed(Freq::Time value) { - return m_ulPassedTime > value.ms(); + return m_ulPassedTime > value.ui(); } Freq::Time age() const { return Freq::Time::ms(m_ulPassedTime); @@ -225,7 +224,7 @@ class Freq } Freq::Time pause() { - return Freq::Time(m_ulAlarmTime - m_ulStartTime); + return Freq::Time::ms(m_ulAlarmTime - m_ulStartTime); } void minutes(unsigned int m) @@ -277,7 +276,7 @@ class Freq Freq::Time excess() const { if(!elapsed()) return Freq::Time(0); - return Freq::Time(m_pTimer->ms() - m_ulAlarmTime); + return Freq::Time::ms(m_pTimer->ms() - m_ulAlarmTime); } boost::signals2::connection connect(std::function cb) { diff --git a/lib/local_shared_ptr b/lib/local_shared_ptr deleted file mode 160000 index fdaef36..0000000 --- a/lib/local_shared_ptr +++ /dev/null @@ -1 +0,0 @@ -Subproject commit fdaef36ff4edecd5c055674fd2bf2e53a6433eed diff --git a/lib/local_shared_ptr b/lib/local_shared_ptr new file mode 120000 index 0000000..42c8092 --- /dev/null +++ b/lib/local_shared_ptr @@ -0,0 +1 @@ +/home/flipcoder/Projects/local_shared_ptr \ No newline at end of file From 538abe846bc59534bae67af73fce77e36b0b4003 Mon Sep 17 00:00:00 2001 From: Grady O'Connell Date: Thu, 21 Mar 2019 02:00:38 -0700 Subject: [PATCH 04/10] fixed subbmodule, added explicit tribool casting --- .gitmodules | 3 ++- kit/kit.h | 12 ++++++------ lib/local_shared_ptr | 2 +- 3 files changed, 9 insertions(+), 8 deletions(-) mode change 120000 => 160000 lib/local_shared_ptr diff --git a/.gitmodules b/.gitmodules index 811098a..0d93a3a 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,4 @@ + [submodule "lib/local_shared_ptr"] path = lib/local_shared_ptr - url = https://github.com/flipcoder/local_shared_ptr + url = git@github.com:flipcoder/local_shared_ptr.git diff --git a/kit/kit.h b/kit/kit.h index 87639fe..5733e28 100644 --- a/kit/kit.h +++ b/kit/kit.h @@ -891,12 +891,12 @@ namespace kit inline bool any_eq(const boost::any& a, const boost::any& b) { if(a.type() != b.type()) return false; - {auto r = any_eq_type(a,b); if(r>=0) return r; } - {auto r = any_eq_type(a,b); if(r>=0) return r;} - {auto r = any_eq_type(a,b); if(r>=0) return r;} - {auto r = any_eq_type(a,b); if(r>=0) return r;} - {auto r = any_eq_type(a,b); if(r>=0) return r;} - {auto r = any_eq_type(a,b); if(r>=0) return r;} + {auto r = any_eq_type(a,b); if(r>=0) return bool(r); } + {auto r = any_eq_type(a,b); if(r>=0) return bool(r);} + {auto r = any_eq_type(a,b); if(r>=0) return bool(r);} + {auto r = any_eq_type(a,b); if(r>=0) return bool(r);} + {auto r = any_eq_type(a,b); if(r>=0) return bool(r);} + {auto r = any_eq_type(a,b); if(r>=0) return bool(r);} throw std::runtime_error("unable to compare values"); } diff --git a/lib/local_shared_ptr b/lib/local_shared_ptr deleted file mode 120000 index 42c8092..0000000 --- a/lib/local_shared_ptr +++ /dev/null @@ -1 +0,0 @@ -/home/flipcoder/Projects/local_shared_ptr \ No newline at end of file diff --git a/lib/local_shared_ptr b/lib/local_shared_ptr new file mode 160000 index 0000000..fdaef36 --- /dev/null +++ b/lib/local_shared_ptr @@ -0,0 +1 @@ +Subproject commit fdaef36ff4edecd5c055674fd2bf2e53a6433eed From 838307a1c0934e3cf33e305c093cb6bad58071fa Mon Sep 17 00:00:00 2001 From: Grady O'Connell Date: Tue, 13 Aug 2019 14:58:32 -0700 Subject: [PATCH 05/10] args key-value tests --- kit/meta/schema.h | 4 +++- tests/args.test.cpp | 11 +++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/kit/meta/schema.h b/kit/meta/schema.h index 232fc3d..c395e37 100644 --- a/kit/meta/schema.h +++ b/kit/meta/schema.h @@ -59,7 +59,9 @@ class SchemaBase Ptr> m_pSchema; }; -using Schema = SchemaBase; +using Schema = SchemaBase; +using SchemaL = SchemaBase; +using SchemaS = SchemaBase; using SchemaMT = SchemaBase; #include "schema.inl" diff --git a/tests/args.test.cpp b/tests/args.test.cpp index 003e386..2f1cea9 100644 --- a/tests/args.test.cpp +++ b/tests/args.test.cpp @@ -62,8 +62,16 @@ TEST_CASE("Args","[args]") { REQUIRE(not args.has('b', "bchar")); REQUIRE(args.has('c', "cchar")); } + + SECTION("key-value") { + Args args; + REQUIRE_NOTHROW(args = Args(vector{"--foo=bar"})); + REQUIRE(args.value("foo") == "bar"); + REQUIRE(args.value_or("foo","baz") == "bar"); + REQUIRE(args.value_or("bin","baz") == "baz"); + } - SECTION("schemas") { + SECTION("expected") { Args args; REQUIRE_NOTHROW(args = Args(vector{"--foo"}, "-f --foo")); @@ -87,7 +95,6 @@ TEST_CASE("Args","[args]") { // -c invalid REQUIRE_THROWS(Args(vector{"-abc"}, "-a -b")); } - } } From 561beac7fed5666bd8643c7526aebf3224b683b9 Mon Sep 17 00:00:00 2001 From: Grady O'Connell Date: Fri, 16 Aug 2019 19:50:45 -0700 Subject: [PATCH 06/10] meta type_ids --- kit/meta/meta.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/kit/meta/meta.h b/kit/meta/meta.h index 3687e8c..e2b9f5b 100644 --- a/kit/meta/meta.h +++ b/kit/meta/meta.h @@ -748,6 +748,13 @@ class Meta_: // >() //); + MetaType::ID type_id(const std::string& key) const { + return m_Elements.at(m_Keys.at(key)).type.id; + } + MetaType::ID type_id(unsigned idx) const { + return m_Elements.at(idx).type.id; + } + unsigned id(const std::string& key) { auto l = this->lock(); return m_Keys.at(key); From a14f9a730aa2ceeb70209d18a296a694a8f31cd5 Mon Sep 17 00:00:00 2001 From: Grady O'Connell Date: Tue, 10 Nov 2020 21:52:58 -0800 Subject: [PATCH 07/10] fixed Args::any() --- kit/args/args.h | 3 ++- tests/args.test.cpp | 10 ++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/kit/args/args.h b/kit/args/args.h index a9fc355..8a625b1 100644 --- a/kit/args/args.h +++ b/kit/args/args.h @@ -62,7 +62,8 @@ class Args bool any(const std::vector& v) const { for(auto&& s: v) - return kit::has(m_Args, s); + if(kit::has(m_Args, s)) + return true; return false; } bool has(const std::string& s) const { diff --git a/tests/args.test.cpp b/tests/args.test.cpp index 2f1cea9..4d00838 100644 --- a/tests/args.test.cpp +++ b/tests/args.test.cpp @@ -63,6 +63,16 @@ TEST_CASE("Args","[args]") { REQUIRE(args.has('c', "cchar")); } + SECTION("any") { + Args args; + args = Args(vector{"foo", "bar"}); + REQUIRE(not args.any({"bin"})); + REQUIRE(not args.any({"bin","baz"})); + REQUIRE(args.any({"bar","bin"})); + REQUIRE(args.any({"bin","bar"})); + REQUIRE(args.any({"foo","bar"})); + } + SECTION("key-value") { Args args; REQUIRE_NOTHROW(args = Args(vector{"--foo=bar"})); From d98aaf087ae6cc07f080da6f6de2c3a9b5136a12 Mon Sep 17 00:00:00 2001 From: Grady O'Connell Date: Wed, 11 Nov 2020 17:36:35 -0800 Subject: [PATCH 08/10] better Args handling of individual char switches --- kit/args/args.cpp | 64 +++++++++++++++++++++++++++++++++++++++++++-- kit/args/args.h | 51 +++++++++++++++++++++++++++--------- tests/args.test.cpp | 61 ++++++++++++++++++++++++++---------------- 3 files changed, 138 insertions(+), 38 deletions(-) diff --git a/kit/args/args.cpp b/kit/args/args.cpp index 14e2937..c550867 100644 --- a/kit/args/args.cpp +++ b/kit/args/args.cpp @@ -18,7 +18,7 @@ void Args :: analyze() if(boost::starts_with(arg, "--")) { if(arg.length()==2) - after_sep = true; + after_sep = true; // empty -- is a separator if(!after_sep) { @@ -34,14 +34,74 @@ void Args :: analyze() if(!value.empty()) if(!m_Values.insert({key,value}).second) throw exception(); // failed to insert + + m_Switches.insert(remove_dashes(key)); // insert key as switch + } + else + { + m_Switches.insert(remove_dashes(arg)); // just a switch, --test is test } } } - else if(not boost::starts_with(arg, "-")) + else if(boost::starts_with(arg, "-")) // only one dash? (above check is two) + { + string flags = arg.substr(1); // remove one dash + for(auto&& ch: flags) + m_Switches.insert(string()+ch); // add chars separately + } + else + { + // no - or --, assume its a filename m_Filenames.push_back(arg); + } } } +string Args :: remove_dashes(string s, bool* success) // static +{ + if(success) + *success = false; + + if(boost::starts_with(s,"--")) + { + s = s.substr(2); + if(success) + *success = true; + } + else if(boost::starts_with(s,"-")) + { + s = s.substr(1); + if(success) + *success = true; + } + return s; +} + +bool Args :: has(std::string op) const +{ + bool removed; + string flag = remove_dashes(op, &removed); + if(not removed) + return kit::has(m_Args, op); + + if(not flag.empty()) + return kit::has(m_Switches, flag); + + assert(false); +} + +bool Args :: has(char ch, std::string op) const +{ + if(boost::starts_with(op, "--")) + op = op.substr(2); // remove -- + else if(boost::starts_with(op, "-")) + op = op.substr(1); + auto flag = string()+ch; + return (kit::has(m_Switches, flag) || + (not op.empty() && kit::has(m_Switches, op)) + ); +} + void Args :: schema(std::string docstring) { if(docstring.empty()) diff --git a/kit/args/args.h b/kit/args/args.h index 8a625b1..c6c0dc6 100644 --- a/kit/args/args.h +++ b/kit/args/args.h @@ -4,6 +4,7 @@ #include #include #include +#include #include "../kit.h" #include #include @@ -66,9 +67,12 @@ class Args return true; return false; } - bool has(const std::string& s) const { - return kit::has(m_Args, s); - } + + // [OLD] + //bool has(const std::string& s) const { + // return kit::has(m_Args, s); + //} + bool has_before( const std::string& match, const std::string& sep ) const { @@ -227,16 +231,26 @@ class Args } } - // tests for a switch and its associated char - bool has(char c, std::string s) const { - assert(not boost::starts_with(s, "--")); - return has(c) || has(std::string("--")+s); - } - bool has(char c) const { - std::string chs = chars(); - return chs.find(c) != std::string::npos; - } - // returns string containing all provided char switches + // [OLD] tests for a switch and its associated char + //bool has(char c, std::string s) const { + // if(boost::starts_with(s, "--")) + // s = s.substr(2); // remove -- + // else if(boost::starts_with(s, "-")) + // s = s.substr(1); + // if(has(c) || has(std::string("--")+s) + // return true; + // if(option(c,s)) + // return true; + // return false; + //} + + // [DEPRECATED] + //bool has(char c) const { + // std::string chs = chars(); + // return chs.find(c) != std::string::npos; + //} + + // [DEPRECATED] returns string containing all provided char switches std::string chars() const { std::string r; for(auto&& a: m_Args) @@ -288,8 +302,13 @@ class Args m_Filename = fn; } + bool has(std::string op) const; + bool has(char ch, std::string full = std::string()) const; + private: + static std::string remove_dashes(std::string s, bool* success = nullptr); + struct Schema { std::vector allowed; @@ -305,6 +324,12 @@ class Args std::map m_Values; std::string m_Filename; boost::optional m_Schema; + + // all options broken down separately + // ./program -abc --test + // will contain -a, -b, -c, and --test + // use has() to check this + std::set m_Switches; }; #endif diff --git a/tests/args.test.cpp b/tests/args.test.cpp index 4d00838..77f4b9c 100644 --- a/tests/args.test.cpp +++ b/tests/args.test.cpp @@ -29,18 +29,20 @@ TEST_CASE("Args","[args]") { SECTION("has") { // empty Args args; - REQUIRE(not args.has("foobar")); + REQUIRE(not args.has("foo")); + REQUIRE(not args.has("-f")); + REQUIRE(not args.has("--foobar")); // single arg - args = Args(vector{"foobar"}); - REQUIRE(args.has("foobar")); - REQUIRE(not args.has("foo")); + args = Args(vector{"--foobar"}); + REQUIRE(args.has("--foobar")); + REQUIRE(not args.has("--foo")); // multiple args - args = Args(vector{"foo", "bar"}); - REQUIRE(args.has("foo")); - REQUIRE(args.has("bar")); - REQUIRE(not args.has("baz")); + args = Args(vector{"--foo", "--bar"}); + REQUIRE(args.has("--foo")); + REQUIRE(args.has("--bar")); + REQUIRE(not args.has("--baz")); // switches args = Args(); @@ -52,25 +54,38 @@ TEST_CASE("Args","[args]") { REQUIRE(args.has('v', "verbose")); // single char REQUIRE(not args.has('n', "nope")); - // multiple char switches - args = Args(vector{"-abc"}, "-a -b -c"); - REQUIRE(args.has('a', "achar")); - REQUIRE(args.has('b', "bchar")); - REQUIRE(args.has('c', "cchar")); - args = Args(vector{"-ac"}, "-a -b -c"); - REQUIRE(args.has('a', "achar")); - REQUIRE(not args.has('b', "bchar")); - REQUIRE(args.has('c', "cchar")); + // multiple char switches (not combined) + //args = Args(vector{"-abc"}, "-a -b -c"); + //REQUIRE(args.has('a', "achar")); + //REQUIRE(args.has('b', "bchar")); + //REQUIRE(args.has('c', "cchar")); + //args = Args(vector{"-ac"}, "-a -b -c"); + //REQUIRE(args.has('a', "achar")); + //REQUIRE(not args.has('b', "bchar")); + //REQUIRE(args.has('c', "cchar")); } + SECTION("option") { + Args args; + args = Args(vector{"-abc", "-d", "--go"}); + REQUIRE(args.has('a')); + REQUIRE(args.has("-a")); + REQUIRE(args.has('b', "berry")); + REQUIRE(args.has('c')); + REQUIRE(args.has('d', "door")); + REQUIRE(not args.has('e')); + REQUIRE(not args.has('f', "foo")); + REQUIRE(args.has('g', "go")); + } + SECTION("any") { Args args; - args = Args(vector{"foo", "bar"}); - REQUIRE(not args.any({"bin"})); - REQUIRE(not args.any({"bin","baz"})); - REQUIRE(args.any({"bar","bin"})); - REQUIRE(args.any({"bin","bar"})); - REQUIRE(args.any({"foo","bar"})); + args = Args(vector{"--foo", "--bar"}); + REQUIRE(not args.any({"--bin"})); + REQUIRE(not args.any({"--bin","--baz"})); + REQUIRE(args.any({"--bar","--bin"})); + REQUIRE(args.any({"--bin","--bar"})); + REQUIRE(args.any({"--foo","--bar"})); } SECTION("key-value") { From bdd7c9eda488d8851debc0d57485f99f1a43c8d1 Mon Sep 17 00:00:00 2001 From: Grady O'Connell Date: Tue, 29 Dec 2020 11:16:41 -0800 Subject: [PATCH 09/10] file_to_string, PATH_SEP, debug log macros, fs->kit namespace --- kit/fs/fs.h | 12 ++-- kit/kit.h | 26 +++++++++ kit/log/log.h | 19 +++++++ kit/meta/meta.h | 8 +-- kit/meta/meta.inl | 139 +++++++++++++++++++++++++++++++++++++++++++++- tests/fs.test.cpp | 13 ++++- 6 files changed, 202 insertions(+), 15 deletions(-) diff --git a/kit/fs/fs.h b/kit/fs/fs.h index 1c2c4db..61c23dd 100644 --- a/kit/fs/fs.h +++ b/kit/fs/fs.h @@ -5,14 +5,14 @@ #include #include "../log/log.h" -namespace fs { - #ifdef _WIN32 -#define SEP "\\" + static const std::string PATH_SEP = "\\"; #else -#define SEP "/" + static const std::string PATH_SEP = "/"; #endif +namespace kit { + inline std::string homedir() { const char* homedir = getenv("HOME"); if(!homedir) @@ -42,13 +42,13 @@ namespace fs { #ifdef _WIN32 r = std::string(cdir); #else - r = std::string(cdir) + SEP + ".config"; + r = std::string(cdir) + PATH_SEP + ".config"; #endif } else r = cdir; if(not apppath.empty()) - return r + SEP + apppath; + return r + PATH_SEP + apppath; return r; } } diff --git a/kit/kit.h b/kit/kit.h index 5733e28..9cf163e 100644 --- a/kit/kit.h +++ b/kit/kit.h @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -1176,6 +1177,31 @@ namespace kit return a + (b-a)*t; } + inline std::vector file_to_buffer(const std::string& fn) + { + std::ifstream file(fn); + if(!file) + return std::vector(); + std::vector data( + (std::istreambuf_iterator(file)), + std::istreambuf_iterator() + ); + data.push_back('\0'); + return data; + } + + inline std::string file_to_string(const std::string & fn) + { + std::ifstream file(fn); + if (!file) + return std::string(); + std::string data( + (std::istreambuf_iterator(file)), + std::istreambuf_iterator() + ); + return data; + } + #define TRY(expr) try{ expr; } catch(...) {} #define TRY_OR(expr, alt) [&]{try{ return (expr); } catch(...) {return (alt);}}() #define IF_OR(expr, alt) [&]{try{ auto r = (expr);if(r)return r; } catch(...) {}return (alt);}() diff --git a/kit/log/log.h b/kit/log/log.h index 4f5aa09..d0a46b0 100644 --- a/kit/log/log.h +++ b/kit/log/log.h @@ -408,6 +408,25 @@ class Log: throw Error(ErrorCode::CODE, _msg);\ } +#ifdef _DEBUG + #define DEBUG_LOG(X) LOG(X) + #define DEBUG_LOGf(X,Y) LOGf(X,Y) + #define DEBUG_WARNING(X) WARNING(X) + #define DEBUG_WARNINGf(X,Y) WARNINGf(X,Y) + // this will only write the error in debug, otherwise assert(false); + #define DEBUG_ERROR(CODE,X) ERROR(CODE,X) + #define DEBUG_ERRORf(CODE,X,Y) ERRORf(CODE,X,Y) +#else + #define DEBUG_LOG(X) + #define DEBUG_LOGf(X,Y) + #define DEBUG_WARNING(X) + #define DEBUG_WARNINGf(X,Y) + // this will only write the error in debug, otherwise assert(false); + #define DEBUG_ERROR(CODE,X) assert(false); + #define DEBUG_ERRORf(CODE,X,Y) assert(false); +#endif + + //#ifdef DEBUG // #define _()\ // Log::Indent _li(\ diff --git a/kit/meta/meta.h b/kit/meta/meta.h index e2b9f5b..48f7c75 100644 --- a/kit/meta/meta.h +++ b/kit/meta/meta.h @@ -697,7 +697,7 @@ class Meta_: * * TODO: timeout callback if we hit a lock * TODO: incremental behavior (merge only what you can without locking) - * so you can loop this until `t` is empty) + * so you can loop this until `t` is empty) -- warning: destructive * * For throw-on-conflict behavior, throw inside of `which` */ @@ -733,7 +733,7 @@ class Meta_: const std::string& fn, unsigned flags = (unsigned)MergeFlags::DEFAULTS // MergeFlags ); - + //void merge( // const Meta_& t, // unsigned flags = (unsigned)MergeFlags::DEFAULTS, @@ -1511,8 +1511,8 @@ class Meta_: // Use these instead of defines using Meta = Meta_; using MetaS = Meta_; -using MetaL = Meta_; -using MetaMT = Meta_; +using MetaL = Meta_; +using MetaMT = Meta_; #include "meta.inl" diff --git a/kit/meta/meta.inl b/kit/meta/meta.inl index 1465c3d..a94124d 100644 --- a/kit/meta/meta.inl +++ b/kit/meta/meta.inl @@ -16,8 +16,10 @@ Meta_ :: Meta_(const std::string& fn, unsigned flags): template class Ptr, template class This> Meta_ :: Meta_(const Ptr>& rhs) { - clear(); - merge(rhs); + //clear(); + //auto tmp = make_shared(); + //tmp->merge(rhs); + //merge(rhs); } template class Ptr, template class This> @@ -1079,3 +1081,136 @@ template class Ptr, template class This return MetaFormat::UNKNOWN; } +//template class Ptr, template class This> +//static std::shared_ptr Meta_ :: copy() +//{ +// assert(t); + +// auto l = lock(); + +// if(!timeout) +// std::lock(al, bl); +// else +// { +// if(std::try_lock(al, bl) != -1) // failed to this->lock +// { +// // incremental merges only try subtrees once and only if they have +// // timeouts +// auto spthis = this->shared_from_this(); +// if(flags & (unsigned)MergeFlags::INCREMENTAL) +// { +// // bail if no timeout function or if timeout returns false +// if(!timeout || !timeout(spthis)) +// return; +// // timeout told us to retry once more +// if(std::try_lock(al, bl) != -1) +// return; +// } +// else +// { +// do { +// if(!timeout(spthis)) +// return; // give up +// }while(std::try_lock(al, bl) == -1); +// } +// } +// } + +// for(auto&& e: t->elements_ref()) +// { +// if(visit) +// visit(t, e); + +// if(e.key.empty()) +// m_Elements.push_back(e); +// else if(m_Keys.find(e.key)==m_Keys.end()) +// { +// m_Elements.push_back(e); +// m_Keys[e.key] = m_Elements.size()-1; +// } +// else +// { +// // already there, merge? +// unsigned this_id = m_Keys[e.key]; +// auto&& this_e = m_Elements[this_id]; +// if(this_e.type.id == MetaType::ID::META && +// e.type.id == MetaType::ID::META// && +// //this_e.type.storage == MetaType::Ptr::SHARED && +// // e.type.storage == MetaType::Ptr::SHARED +// ){ +// if(flags & (unsigned)MergeFlags::RECURSIVE) +// { +// //try{ +// at>>(this_id)->merge( +// t->template at>>(e.key), +// which, +// flags, +// timeout +// ); +// //}catch(const kit::null_ptr_exception&){} +// } +// else +// { +// auto r = which(this_e, e); +// Meta_::Which* w = boost::get(&r); +// if(!w) +// { +// MetaElement* a = boost::get(&r); +// auto preserved_key = this_e.key; +// if(flags & (unsigned)MergeFlags::INCREMENTAL) +// this_e = std::move(*a); +// else +// this_e = *a; +// this_e.key = preserved_key; +// } +// else if(*w == Which::RECURSE) +// { +// auto m = at>>(this_id); +// assert(m); +// m->merge( +// t->template at>>(e.key), +// which, +// flags, +// timeout +// ); +// // delete entire null trees in destructive merges +// if(flags & (unsigned)MergeFlags::INCREMENTAL) +// { +// if(m->all_empty()) +// { +// m->clear(); +// e.nullify(); +// } +// } +// } +// else if(*w == Which::OTHER) +// { +// replace(this_id, e); +// if(flags & (unsigned)MergeFlags::INCREMENTAL) +// e.nullify(); +// } +// else if(*w == Which::NEITHER) +// { +// remove(this_id); +// if(flags & (unsigned)MergeFlags::INCREMENTAL) +// e.nullify(); +// } + +// // TODO: other Meta_::Which values (except Which::SELF, +// // that can be treated simply by continue; below) +// // Meta_::Which values have preference over flags below +// // so we continue; here + +// continue; +// } +// } + +// if(flags & (unsigned)MergeFlags::REPLACE) { +// replace(this_id, e); +// e.nullify(); +// } +// } +// } + +//} + diff --git a/tests/fs.test.cpp b/tests/fs.test.cpp index 91e98e1..f08bc2c 100644 --- a/tests/fs.test.cpp +++ b/tests/fs.test.cpp @@ -5,9 +5,16 @@ using namespace std; TEST_CASE("fs","[fs]") { SECTION("usage") { - cout << fs::homedir() << endl; - cout << fs::configdir() << endl; - cout << fs::configdir("test") << endl; + // TODO: write OS-specific tests + + // $HOME or $HOMEPATH + cout << kit::homedir() << endl; + + // $XDG_CONFIG_HOME or $HOME/.config on Linux + cout << kit::configdir() << endl; + + // $XDG_CONFIG_HOME/test or $HOME/.config/test on Linux + cout << kit::configdir("test") << endl; } } From 4e2065763f84f55c0ca7a90456aed361eef96960 Mon Sep 17 00:00:00 2001 From: Grady O'Connell Date: Tue, 29 Dec 2020 11:18:38 -0800 Subject: [PATCH 10/10] uncommented merge() call from last commit --- kit/meta/meta.inl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kit/meta/meta.inl b/kit/meta/meta.inl index a94124d..9eb44ad 100644 --- a/kit/meta/meta.inl +++ b/kit/meta/meta.inl @@ -19,7 +19,7 @@ Meta_ :: Meta_(const Ptr>& rhs) //clear(); //auto tmp = make_shared(); //tmp->merge(rhs); - //merge(rhs); + merge(rhs); } template class Ptr, template class This>