Skip to content

Conversation

@eguiraud
Copy link
Contributor

Here it is...any kind of feedback welcome :)

@phsft-bot
Copy link

Starting build on gcc49/centos7, native/mac1012, gcc49/slc6, gcc62/slc6, native/ubuntu14 with flags -Dvc=OFF -Dimt=ON -Dccache=ON
How to customize builds

1 similar comment
@phsft-bot
Copy link

Starting build on gcc49/centos7, native/mac1012, gcc49/slc6, gcc62/slc6, native/ubuntu14 with flags -Dvc=OFF -Dimt=ON -Dccache=ON
How to customize builds

@eguiraud
Copy link
Contributor Author

A google test is on the way

@phsft-bot
Copy link

@phsft-bot
Copy link

@phsft-bot
Copy link

@phsft-bot
Copy link

@phsft-bot
Copy link

*************************************************************************/

#ifndef ROOT_TTypeTraits
#define ROOT_TTypeTraits
Copy link
Member

Choose a reason for hiding this comment

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

Isn't this supposed to drop the extra T as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

good catch, thanks!

@phsft-bot
Copy link

Starting build on gcc49/centos7, native/mac1012, gcc49/slc6, gcc62/slc6, native/ubuntu14 with flags -Dvc=OFF -Dimt=ON -Dccache=ON
How to customize builds

@eguiraud
Copy link
Contributor Author

A google test has been added in $ROOTSYS/core/foundation/test. roottest_dataframe_functiontraits has been broken by moving the meta utils away from TDataFrame, and is removed by PR n.48 in roottest.

@phsft-bot
Copy link

@phsft-bot
Copy link

@phsft-bot
Copy link

@phsft-bot
Copy link

@phsft-bot
Copy link

@dpiparo
Copy link
Member

dpiparo commented Jun 13, 2017

@phsft-bot build please.

@phsft-bot
Copy link

Starting build on gcc49/centos7, native/mac1012, gcc49/slc6, gcc62/slc6, native/ubuntu14 with flags -Dvc=OFF -Dimt=ON -Dccache=ON
How to customize builds

};

template <int D, typename P, template <int, typename, template <typename> class> class... S>
struct IsV7Hist<ROOT::Experimental::THist<D, P, S...>> : public std::true_type {
Copy link
Member

Choose a reason for hiding this comment

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

Could we move these two back to an internal file, it is not quite 'general' enough :) [ i.e. ROOT implementation detail]

Copy link
Contributor Author

Choose a reason for hiding this comment

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

we don't want ROOT type traits in ROOT/TypeTraits? :) note that it does not introduce a dependency on libHisto, it just needs a forward decl

Copy link
Contributor Author

Choose a reason for hiding this comment

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

moved back to TDataFrame

/// e.g. TakeFirstParameter<U<A,B>> is A
/// TakeFirstParameter<T> is T
template <typename T>
struct TakeFirstParameter {
Copy link
Member

Choose a reason for hiding this comment

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

What is the difference between TakeFirst and TakeFirstParameter? Do we need both? Can we distinguish them more?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

TakeFirst acts on variadic lists of types, e.g. TakeFirst_t<A,B> is A. TakeFirstParameter acts on the parameter list of a template object, e.g. TakeFirstParameter_t<U<A,B>> is A. They do different things, so I would say we "need" them both. I'm open to suggestions regarding the names (TakeFirstType and TakeFirstParameter?). I thought the docs were clear but maybe not?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

renamed to TakeFirstType

Copy link
Member

Choose a reason for hiding this comment

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

I suppose your renamed the first one (formely TakeFirst), in which case, this is indeed better. thanks

@phsft-bot
Copy link

Build failed on mac1012/native.
See console output.

Warnings:

Failing tests:

@@ -0,0 +1,143 @@
#include "ROOT/TypeTraits.hxx"
Copy link
Member

Choose a reason for hiding this comment

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

Can we please rename the test file either TypeTraits.test.cxx (or testTypeTrait.cxx) to distinguish it (beyhond just the directory) from an implementation file? Thanks.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

sure

Copy link
Member

Choose a reason for hiding this comment

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

We were using EntityToTestTests.cxx pattern. Having something/test/test*.cxx looks very weird...

Copy link
Member

Choose a reason for hiding this comment

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

Who's "we"? ls */*/test/*.cxx seems to disagree...

@phsft-bot
Copy link

Starting build on gcc49/centos7, native/mac1012, gcc49/slc6, gcc62/slc6, native/ubuntu14 with flags -Dvc=OFF -Dimt=ON -Dccache=ON
How to customize builds

Copy link
Member

@Axel-Naumann Axel-Naumann left a comment

Choose a reason for hiding this comment

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

Generally, please consider moving declarations into Detail:: or even Internal::: the latter allows us to change these declarations without notice.

using Test_t = typename std::decay<T>::type;

template <typename A>
static constexpr bool Test(A *pt, A const *cpt = nullptr, decltype(pt->begin()) * = nullptr,
Copy link
Member

Choose a reason for hiding this comment

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

I'd have written that as

template<class A,
  class NonConstA = typename std::remove_const<A>::type,
  class ConstA = typename std::add_const<A>::type>
Test(NonConstA::iterator = {},
   ConstA::const_iterator = {},
   NonConstA::iterator = decltype(NonConstA().begin())()
   NonConstA::iterator = decltype(NonConstA().end())(),
   ConstA::const_iterator = decltype(ConstA().begin())(),
   ConstA::const_iterator = decltype(ConstA().end())(),
   bool = typename std::is_same<delctype(*ConstA::const_iterator()), typename add_const<ConstA::value_type>::type>::value,
   bool = typename std::is_same<delctype(*NonConstA::iterator()), ConstA::value_type>::value)

This ensures that

  • the container and (const_)iterator are default constructible
  • there is a (const_)iterator that matches the return types of begin() and end(), const and non-const versions,
  • (const_)iterator can be derefed giving (const) value_type

I see you have more tests in the body. Note that e.g. **piwill trigger a compilation failure if iterator has no deref, instead of returning false, which is why I added checks to the signature. More might be needed.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for looking into this. This was implemented by @dpiparo so I would ask his opinion too.

Copy link
Member

Choose a reason for hiding this comment

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

Hi @bluehood , @Axel-Naumann I am of course fine with the new implementation!


/// Check whether a histogram type is a classic or v7 histogram.
template <typename T>
struct IsV7Hist : public std::false_type {
Copy link
Member

Choose a reason for hiding this comment

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

I don't think we need this in the public part of the type traits. Maybe at least ROOT::Detail:: if not ROOT::Internal? Do you think we'll have more uses?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@pcanal expressed the same concern. I'm outnumbered, so I'll move IsV7Hist back inside TDataFrame's stuff.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

};

/// Extract types from the signature of a callable object.
template <typename T>
Copy link
Member

Choose a reason for hiding this comment

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

I would make the generic one empty. Then have a specialization for those T that have a call operator.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

will do

struct CallableTraits {
using arg_types = typename CallableTraits<decltype(&T::operator())>::arg_types;
using arg_types_nodecay = typename CallableTraits<decltype(&T::operator())>::arg_types_nodecay;
using ret_type = typename CallableTraits<decltype(&T::operator())>::ret_type;
Copy link
Member

Choose a reason for hiding this comment

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

Can you spell the result (please use the std wording here) type using result_of and invoke_result, for all cases, moving the arg_types deduction into a helper detail struct that you then partially specialize?

Copy link
Member

Choose a reason for hiding this comment

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

Let me rephrase:

struct foo{
  int operator()(int);
  double operator()(double);
};
using res = typename CallableTraits<foo(float)>::ret_type;

should res be double or should this be ill-formed?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

What is the standard wording? result_of and invoke_result contain a type, but I think it would be a confusing name here? boost uses return_type in their function_traits, I can change it to that if you prefer.

Your example should be ill-formed because CallableTraits does not require to specify the argument types, users just pass in a callable object. Supporting the syntax you used might be a nice addition but we have no use for it, at least for now.

Copy link
Member

Choose a reason for hiding this comment

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

Forget what I said - you test the callable, not the expression. Return type is just fine.


// mutable lambdas and functor classes
template <typename R, typename T, typename... Args>
struct CallableTraits<R (T::*)(Args...)> {
Copy link
Member

Choose a reason for hiding this comment

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

You allow for non-member function references but not for member function references. Intentional?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Can you give me an example?

This works:

struct A { void foo() {} };
static_assert(std::is_same<CallableTraits<decltype(&A::foo)>::ret_type, void>::value, "");

Copy link
Member

Choose a reason for hiding this comment

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

Does static_assert(std::is_same<CallableTraits<decltype(A::foo)>::ret_type, void>::value, ""); work?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It does not. Can you ever use decltype(A::foo) anywhere?

Copy link
Member

Choose a reason for hiding this comment

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

Indeed, thanks! Forget this comment, too! :-)

/// Return first of possibly many template parameters.
/// For non-template types, the result is the type itself.
/// e.g. TakeFirstParameter<U<A,B>> is A
/// TakeFirstParameter<T> is T
Copy link
Member

Choose a reason for hiding this comment

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

That is a very ... rare ... behavior. Providing this as a general tool might see misuses / misunderstanding of the interface. I'd naively expect that TakeFirstParameter<T> is either empty or ill-formed, instead of mixing template levels... Do you expect generic usage of this? (Do you really know you need this behavior in your use case? I didn't look at it, it seems surprising...)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I agree, I will change the behaviour

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done


/// Compile-time integer sequence generator
/// e.g. calling GenStaticSeq<3>::type() instantiates a StaticSeq<0,1,2>
// TODO deprecate as soon as std::index_sequence is backported
Copy link
Member

Choose a reason for hiding this comment

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

Can we move this into Experimental::? Then we can just remove it without deprecation, and for now, no other interfaces should be using it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I am never sure when it comes to ROOT namespaces. Do you mean ROOT::Experimental:: or ROOT::TypeTraits::Experimental:: or ROOT::Experimental::TypeTraits::?

Copy link
Member

Choose a reason for hiding this comment

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

Actually since it is not meant to be used by users (std::index_sequence is), I would put it in ::ROOT::Internal (and move it back to DataFrame unless there is another 'current' user ...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'll move it back and push for having a backport of std::index_sequence soon :)

@phsft-bot
Copy link

@phsft-bot
Copy link

Starting build on gcc49/centos7, native/mac1012, gcc49/slc6, gcc62/slc6, native/ubuntu14 with flags -Dvc=OFF -Dimt=ON -Dccache=ON
How to customize builds

@phsft-bot
Copy link

Build failed on centos7/gcc49.
See console output.

Errors:

  • ninja: error: loading 'build.ninja': No such file or directory

Warnings:

@phsft-bot
Copy link

Starting build on gcc49/centos7, native/mac1012, gcc49/slc6, gcc62/slc6, native/ubuntu14 with flags -Dvc=OFF -Dimt=ON -Dccache=ON
How to customize builds

@eguiraud
Copy link
Contributor Author

Rebased and fixed clang-formatting. There are no items pending afaik.

@eguiraud
Copy link
Contributor Author

Rebased on master, resolved conflicts

@dpiparo dpiparo merged commit 04cb79e into root-project:master Jun 27, 2017
@eguiraud eguiraud deleted the type_traits branch June 27, 2017 21:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants