Skip to content

Commit

Permalink
add swisstable
Browse files Browse the repository at this point in the history
  • Loading branch information
abbycin committed Oct 20, 2023
1 parent 634fe05 commit 3ea4bad
Show file tree
Hide file tree
Showing 16 changed files with 1,195 additions and 48 deletions.
4 changes: 1 addition & 3 deletions .clang-format
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: MultiLine
AttributeMacros:
- __capability
BinPackArguments: false
Expand Down Expand Up @@ -108,7 +107,6 @@ IndentCaseBlocks: false
IndentGotoLabels: true
IndentPPDirectives: None
IndentExternBlock: AfterExternBlock
IndentRequires: false
IndentWidth: 8
IndentWrappedFunctionNames: false
InsertTrailingCommas: None
Expand All @@ -135,7 +133,7 @@ PenaltyReturnTypeOnItsOwnLine: 60
PenaltyIndentedWhitespace: 0
PointerAlignment: Right
ReflowComments: true
SortIncludes: false
SortIncludes: Never
SortJavaStaticImport: Before
SortUsingDeclarations: false
SpaceAfterCStyleCast: false
Expand Down
12 changes: 7 additions & 5 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
cmake_minimum_required(VERSION 3.18)
cmake_minimum_required(VERSION 3.25)
project(tools)

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_EXTENSIONS ON)
set(CMAKE_VERBOSE_MAKEFILE ON)

set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Werror -pedantic-errors -O0")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Werror -pedantic-errors")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Werror -Wextra -O0 -g")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Werror -Wextra")

file(GLOB items RELATIVE ${PROJECT_SOURCE_DIR} ${PROJECT_SOURCE_DIR}/*)
foreach(item ${items})
string(REGEX MATCH "^[^\.].*" dot ${item})
if(("${dot}" STREQUAL "") OR (${item} STREQUAL "build"))
string(REGEX MATCH ".*build.*" build ${item})
if(("${dot}" STREQUAL "") OR (NOT ("${build}" STREQUAL "")) OR (${item} STREQUAL "loop_per_thread"))
continue()
endif()
if(IS_DIRECTORY ${PROJECT_SOURCE_DIR}/${item})
Expand Down
10 changes: 4 additions & 6 deletions fake_variant/fake_variant.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,16 +78,14 @@ namespace meta

template<typename T1, typename T2, template<typename> class Class>
class GenClasses<TypeList<T1, T2>, Class>
: public GenClasses<T1, Class>, public GenClasses<T2, Class> {
};
: public GenClasses<T1, Class>,
public GenClasses<T2, Class> { };

template<typename T, template<typename> class Class>
class GenClasses : public Class<T> {
};
class GenClasses : public Class<T> { };

template<template<typename> class Class>
class GenClasses<Nil, Class> {
};
class GenClasses<Nil, Class> { };

}

Expand Down
1 change: 1 addition & 0 deletions instant/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
add_executable(instant main.cc instant.h)
57 changes: 57 additions & 0 deletions instant/instant.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Author: Abby Cin
* Mail: [email protected]
* Create Time: 2023-10-13 10:20:58
*/

#ifndef INSTANT_20231013102058
#define INSTANT_20231013102058

#include <chrono>

namespace nm
{
class Instant {
public:
static Instant now()
{
return { std::chrono::steady_clock::now() };
}

auto elapse_usec()
{
return diff().count() / 1e3;
}

auto elapse_ms()
{
return diff().count() / 1e6;
}

auto elapse_sec()
{
return diff().count() / 1e9;
}

auto elapse_min()
{
return elapse_sec() / 60.0;
}

private:
using timepoint = std::chrono::steady_clock::time_point;
Instant(timepoint now) : tp_ { now }
{
}

auto diff() -> std::chrono::duration<double, std::nano>
{
return std::chrono::steady_clock::now() - tp_;
}

timepoint tp_;
};
}

#endif // INSTANT_20231013102058
40 changes: 40 additions & 0 deletions instant/main.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Author: Abby Cin
* Mail: [email protected]
* Create Time: 2023-10-13 10:21:10
*/

#include "instant.h"
#include <thread>

void die_on_false(bool ok)
{
if (!ok)
abort();
}

int main()
{
using namespace std::chrono_literals;
{
auto e = nm::Instant::now();
std::this_thread::sleep_for(10us);
die_on_false(e.elapse_usec() > 10);
}
{
auto e = nm::Instant::now();
std::this_thread::sleep_for(10ms);
die_on_false(e.elapse_ms() >= 10);
}
{
auto e = nm::Instant::now();
std::this_thread::sleep_for(2s);
die_on_false(e.elapse_sec() >= 2);
}
{
auto e = nm::Instant::now();
std::this_thread::sleep_for(61s);
die_on_false(e.elapse_min() > 1);
}
}
21 changes: 7 additions & 14 deletions meta/function_traits.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,36 +24,29 @@ namespace meta
using res_t = R;
};
template<typename R, typename... Args>
struct Inspector<R (*)(Args...)> : Inspector<R(Args...)> {
};
struct Inspector<R (*)(Args...)> : Inspector<R(Args...)> { };
template<typename R, typename... Args>
struct Inspector<R (&)(Args...)> : Inspector<R(Args...)> {
};
struct Inspector<R (&)(Args...)> : Inspector<R(Args...)> { };
template<typename R, typename Object, typename... Args>
struct Inspector<R (Object::*)(Args...)> : Inspector<R(Args...)> {
};
struct Inspector<R (Object::*)(Args...)> : Inspector<R(Args...)> { };
template<typename R, typename Object, typename... Args>
struct Inspector<R (Object::*)(Args...) const> : Inspector<R(Args...)> {
};
template<typename R, typename Object, typename... Args>
struct Inspector<R (Object::*)(Args...) volatile>
: Inspector<R(Args...)> {
};
: Inspector<R(Args...)> { };
template<typename R, typename Object, typename... Args>
struct Inspector<R (Object::*)(Args...) const volatile>
: Inspector<R(Args...)> {
};
: Inspector<R(Args...)> { };

// functor like
template<typename Lambda>
struct Inspector : Inspector<decltype(&Lambda::operator())> {
};
struct Inspector : Inspector<decltype(&Lambda::operator())> { };
template<typename Lambda>
struct Inspector<Lambda &> : Inspector<decltype(&Lambda::operator())> {
};
template<typename Lambda>
struct Inspector<Lambda &&> : Inspector<Lambda &> {
};
struct Inspector<Lambda &&> : Inspector<Lambda &> { };
}
}

Expand Down
4 changes: 4 additions & 0 deletions swisstable/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
add_executable(swiss_set_test swiss_set_test.cc swisstable.h)
target_include_directories(swiss_set_test PRIVATE ${PROJECT_SOURCE_DIR})

add_executable(swiss_map_test swiss_map_test.cc)
3 changes: 3 additions & 0 deletions swisstable/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pointer stability is not guaranteed

a good hash function is required (see [absl::Hash](https://abseil.io/docs/cpp/guides/hash))
68 changes: 68 additions & 0 deletions swisstable/swiss_map.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Author: Abby Cin
* Mail: [email protected]
* Create Time: 2023-10-16 13:23:04
*/

#ifndef SWISS_MAP_H_20231016132304
#define SWISS_MAP_H_20231016132304

#include "swisstable.h"
#include <initializer_list>

namespace nm
{
template<typename K, typename V>
class MapPolicy {
public:
static_assert(!std::is_reference_v<K>, "forbid reference as key");
using key_type = std::remove_cvref_t<K>;
using value_type = std::pair<key_type, V>;

static const key_type &key(const value_type &v)
{
return v.first;
}
};

template<typename Key,
typename Val,
typename Hash = SwissHash,
typename Eq = SwissEq>
class SwissMap : public detail::Swiss<MapPolicy<Key, Val>, Hash, Eq> {
using Base = detail::Swiss<MapPolicy<Key, Val>, Hash, Eq>;

public:
using Base::Base;
using Base::begin;
using Base::end;
using Base::insert;
using Base::erase;
using Base::reserve;
using Base::find;
using iterator = Base::iterator;

SwissMap(std::initializer_list<typename Base::value_type> il) : Base {}
{
for (auto &x : il)
insert(x);
}

template<typename K, typename V>
iterator emplace(K &&k, V &&v)
{
return insert({ std::forward<K>(k), std::forward<V>(v) });
}

Val &operator[](const Key &k)
{
auto it = find(k);
if (it == end())
it = emplace(k, Val {});
return it->second;
}
};
}

#endif // SWISS_MAP_H_20231016132304
59 changes: 59 additions & 0 deletions swisstable/swiss_map_test.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Author: Abby Cin
* Mail: [email protected]
* Create Time: 2023-10-16 19:51:17
*/

#include "swiss_map.h"

int main()
{
{
nm::SwissMap<int, int> m { { 5, 6 } };

m.emplace(1, 2);
m.emplace(2, 3);
m.emplace(3, 4);

for (auto [k, v] : m)
printf("%d => %d\n", k, v);
auto it = m.find(1);
printf("=> %d %d\n", it->first, it->second);

m.erase(1);
printf("contains 1? %s\n", m.contains(1) ? "yes" : "no");
for (auto [k, v] : m)
printf("%d => %d\n", k, v);

printf("before clear load_factor %f\n", m.load_factor());
m.clear();
for (auto [k, v] : m)
printf("%d => %d\n", k, v);
printf("after clear load_factor %f\n", m.load_factor());
}

{
using namespace std::string_literals;
nm::SwissMap<std::string, int> m { { "e"s, 4 } };

m.emplace("a"s, 1);
m.emplace("b"s, 2);
m.emplace("c"s, 3);

m.insert({ "d"s, 4 });

auto it = m.find("c"s);
auto moha = "moha"s;

it->second = 666;

m[moha] = 1926;
printf("moha => %d\n", m[moha]);

m[moha] = 233;

for (auto &[k, v] : m)
printf("%s => %d\n", k.c_str(), v);
}
}
Loading

0 comments on commit 3ea4bad

Please sign in to comment.