Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial sml version support added #4591

Merged
merged 13 commits into from
Feb 22, 2021
4 changes: 4 additions & 0 deletions recipes/sml/all/conandata.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
sources:
"1.1.4":
url: https://github.com/boost-ext/sml/archive/v1.1.4.tar.gz
sha256: 897c78077f5a4d22b0de253b8689a8ea6d8adfba8d7b4877d6f5c76277e00976
49 changes: 49 additions & 0 deletions recipes/sml/all/conanfile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
from conans import ConanFile, tools
from conans.tools import check_min_cppstd
from conans.errors import ConanInvalidConfiguration
import os


mpusz marked this conversation as resolved.
Show resolved Hide resolved
class SMLConan(ConanFile):
name = "sml"
homepage = "https://github.com/boost-ext/sml"
description = "SML: C++14 State Machine Library"
topics = ("state-machine", "metaprogramming", "design-patterns", "sml")
license = "BSL-1.0"
url = "https://github.com/conan-io/conan-center-index"
settings = "compiler"
no_copy_source = True

@property
def _source_subfolder(self):
return "source_subfolder"

@property
def _minimum_compilers_version(self):
return {
"Visual Studio": "15",
"gcc": "5",
"clang": "5",
"apple-clang": "5.1",
}

def configure(self):
if self.settings.compiler.cppstd:
check_min_cppstd(self, "14")
minimum_version = self._minimum_compilers_version.get(str(self.settings.compiler), False)
if not minimum_version:
self.output.warn("SML requires C++14. Your compiler is unknown. Assuming it supports C++14.")
elif tools.Version(self.settings.compiler.version) < minimum_version:
raise ConanInvalidConfiguration("SML requires C++14, which your compiler does not support.")

def source(self):
tools.get(**self.conan_data["sources"][self.version])
extracted_dir = "sml-" + self.version
os.rename(extracted_dir, self._source_subfolder)

def package(self):
self.copy(pattern="*", dst="include", src=os.path.join(self._source_subfolder, "include"))
self.copy("*LICENSE.md", dst="licenses", keep_path=False)

mpusz marked this conversation as resolved.
Show resolved Hide resolved
def package_id(self):
self.info.header_only()
9 changes: 9 additions & 0 deletions recipes/sml/all/test_package/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
cmake_minimum_required(VERSION 3.5)
project(test_package CXX)

include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
conan_basic_setup(TARGETS)

add_executable(${PROJECT_NAME} test_package.cpp)
target_link_libraries(${PROJECT_NAME} PRIVATE CONAN_PKG::sml)
target_compile_features(${PROJECT_NAME} PUBLIC cxx_std_14)
16 changes: 16 additions & 0 deletions recipes/sml/all/test_package/conanfile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from conans import ConanFile, CMake, tools
import os


class TestPackageConan(ConanFile):
settings = "os", "compiler", "build_type", "arch"
generators = "cmake"

def build(self):
cmake = CMake(self)
cmake.configure()
cmake.build()

def test(self):
if not tools.cross_building(self.settings):
self.run(os.path.join("bin", "test_package"), run_environment=True)
95 changes: 95 additions & 0 deletions recipes/sml/all/test_package/test_package.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
#include <boost/sml.hpp>
#include <cassert>

namespace sml = boost::sml;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://github.com/conan-io/conan-center-index/blob/master/docs/reviewing.md#minimalistic-source-code

Is there any way we can make a cross platform test package? it does not need to do anything just use those headers should be sufficient?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@krzysztof-jusiak, could you please share a simpler cross-platform test example?


namespace {
// events
struct release {};
struct ack {};
struct fin {};
struct timeout {};

// guards
const auto is_ack_valid = [](const ack&) { return true; };
const auto is_fin_valid = [](const fin&) { return true; };

// actions
const auto send_fin = [] {};
const auto send_ack = [] {};

#if !defined(_MSC_VER)
struct hello_world {
auto operator()() const {
using namespace sml;
// clang-format off
return make_transition_table(
*"established"_s + event<release> / send_fin = "fin wait 1"_s,
"fin wait 1"_s + event<ack> [ is_ack_valid ] = "fin wait 2"_s,
"fin wait 2"_s + event<fin> [ is_fin_valid ] / send_ack = "timed wait"_s,
"timed wait"_s + event<timeout> / send_ack = X
);
// clang-format on
}
};
}

int main() {
using namespace sml;

sm<hello_world> sm;
// static_assert(1 == sizeof(sm), "sizeof(sm) != 1b");
assert(sm.is("established"_s));

sm.process_event(release{});
assert(sm.is("fin wait 1"_s));

sm.process_event(ack{});
assert(sm.is("fin wait 2"_s));

sm.process_event(fin{});
assert(sm.is("timed wait"_s));

sm.process_event(timeout{});
assert(sm.is(X)); // released
}
#else
class established;
class fin_wait_1;
class fin_wait_2;
class timed_wait;

struct hello_world {
auto operator()() const {
using namespace sml;
// clang-format off
return make_transition_table(
*state<established> + event<release> / send_fin = state<fin_wait_1>,
state<fin_wait_1> + event<ack> [ is_ack_valid ] = state<fin_wait_2>,
state<fin_wait_2> + event<fin> [ is_fin_valid ] / send_ack = state<timed_wait>,
state<timed_wait> + event<timeout> / send_ack = X
);
// clang-format on
}
};
}

int main() {
using namespace sml;

sm<hello_world> sm;
assert(sm.is(state<established>));

sm.process_event(release{});
assert(sm.is(state<fin_wait_1>));

sm.process_event(ack{});
assert(sm.is(state<fin_wait_2>));

sm.process_event(fin{});
assert(sm.is(state<timed_wait>));

sm.process_event(timeout{});
assert(sm.is(X)); // released
}
#endif
3 changes: 3 additions & 0 deletions recipes/sml/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
versions:
"1.1.4":
folder: all