当前位置: 首页 > news >正文

国外 网站有做验证码吗网站幕布拍照什么样子的

国外 网站有做验证码吗,网站幕布拍照什么样子的,哪个网站教做西餐,佛山企业一般在哪网站发布消息3. LVM有趣的代码 3.1. dyn_cast()与cast() C支持类型间的自动转换#xff08;如operator 声明的转换#xff09;#xff0c;但在转换的调用链里自动转换只能调用一次#xff0c;这固然是避免给编译器带来过分的复杂性#xff0c;但更重要的是允许自动转换接力调用几乎很…3. LVM有趣的代码 3.1. dyn_cast()与cast() C支持类型间的自动转换如operator 声明的转换但在转换的调用链里自动转换只能调用一次这固然是避免给编译器带来过分的复杂性但更重要的是允许自动转换接力调用几乎很难避免出现递归调用而且调用链过长会很快失去控制给人带来意想不到的结果。但是C原生的类型转换系统对于LLVM/MLIR来说局限性太大因此LLVM打造了自己的类型转换系统它仿造C的惯例给出了自己的类型转换函数cast、dyn_cast。显然它们分别对应其他cast与dynamic_cast。它们与C版本的最大不同在于cast、dyn_cast都支持无限次自动转换这在用户眼皮底下发生但用户需要提供一些指定的方法。在这个体系中dyn_cast最有代表性llvm里一共定义了3个版本它们的区别在于函数参数类型 331  template class X, class Y 332  LLVM_NODISCARD inline std::enable_if_t 333      !is_simple_typeY::value, typename cast_rettyX, const Y::ret_type 334  dyn_cast(const Y Val) { 335    return isaX(Val) ? castX(Val) : nullptr; 336  } 337  338  template class X, class Y 339  LLVM_NODISCARD inline typename cast_rettyX, Y::ret_type dyn_cast(Y Val) { 340    return isaX(Val) ? castX(Val) : nullptr; 341  } 342  343  template class X, class Y 344  LLVM_NODISCARD inline typename cast_rettyX, Y *::ret_type dyn_cast(Y *Val) { 345    return isaX(Val) ? castX(Val) : nullptr; 346  } 在这些函数里用到isa()与cast()isa()是这样的它检查参数的类型是否与模板参数里给出的类型一致。 141  template class X, class Y LLVM_NODISCARD inline bool isa(const Y Val) {  // 最终调用的函数 142    return isa_impl_wrapX, const Y, 143                         typename simplify_typeconst Y::SimpleType::doit(Val); 144  } 145  146  template typename First, typename Second, typename... Rest, typename Y 147  LLVM_NODISCARD inline bool isa(const Y Val) { 148    return isaFirst(Val) || isaSecond, Rest...(Val); 149  } 实际上isa()支持对某个类型列表检查指定类型是否与其中一个类型一致。而两个特定类型比较的实现是由isa_impl_wrap这个类提供的 116  templatetypename To, typename From, typename SimpleFrom 117  struct isa_impl_wrap { 118    // When From ! SimplifiedType, we can simplify the type some more by using 119    // the simplify_type template. 120    static bool doit(const From Val) { 121      return isa_impl_wrapTo, SimpleFrom, 122        typename simplify_typeSimpleFrom::SimpleType::doit( 123                            simplify_typeconst From::getSimplifiedValue(Val)); 124    } 125  }; 126  127  templatetypename To, typename FromTy 128  struct isa_impl_wrapTo, FromTy, FromTy { 129    // When From SimpleType, we are as simple as we are going to get. 130    static bool doit(const FromTy Val) { 131      return isa_impl_clTo,FromTy::doit(Val); 132    } 133  }; 为了支持无限次自动转换这里指出了3个类型To、From、SimpleFrom。其中被转换值从From类型转换到SimpleFrom类型这个SimpleFrom类型还可能进一步转换为另一个SimpleFrom类型直到From与SimpleFrom类型一致为止这意味着From不能再“简化了”。这时我们使用128行的isa_impl_wrap特化定义。 首先我们先看一下完成从From到SimpleFrom的simplify_type类。注意如果存在llvm所不知道的From到SimpleFrom的转换必须提供这个目的的simplify_type特化版本。如果不提供将使用simplify_type的非特化版本llvm对自己的数据结构定义了若干simplify_type特化版本 33  templatetypename From struct simplify_type { 34    using SimpleType From; // The real type this represents... 35  36    // An accessor to get the real value... 37    static SimpleType getSimplifiedValue(From Val) { return Val; } 38  }; 39  40  templatetypename From struct simplify_typeconst From { 41    using NonConstSimpleType typename simplify_typeFrom::SimpleType; 42    using SimpleType 43        typename add_const_past_pointerNonConstSimpleType::type; 44    using RetType 45        typename add_lvalue_reference_if_not_pointerSimpleType::type; 46  47    static RetType getSimplifiedValue(const From Val) { 48      return simplify_typeFrom::getSimplifiedValue(const_castFrom(Val)); 49    } 50  }; 可以看到非特化版本的simplify_type通过getSimplifiedValue()给出的SimpleFrom就是值自己。 在simplify_type再也给不出“简化”时isa_impl_wrap提供最后的判断同样它有许多特化版本我们只看llvm的非定制版本好了 55  template typename To, typename From, typename Enabler void 56  struct isa_impl { 57    static inline bool doit(const From Val) { 58      return To::classof(Val);   // -- 最终的裁决者 59    } 60  }; 61  62  /// Always allow upcasts, and perform no dynamic check for them. 63  template typename To, typename From 64  struct isa_implTo, From, std::enable_if_tstd::is_base_ofTo, From::value { 65    static inline bool doit(const From ) { return true; } 66  }; 67  68  template typename To, typename From struct isa_impl_cl { 69    static inline bool doit(const From Val) { 70      return isa_implTo, From::doit(Val); 71    } 72  }; 这里的调用关系始于68行的isa_impl_cl()它所调用的isa_impl()也需要各个类提供自己的特化版本来实现特定的类型转换。在不提供特化版本时如果两个类有继承关系那么就会使用64行llvm的特化版本无条件放行否则由上面58行To的classof()方法来判定它们是否一致。 在dyn_cast()中当isa()认定两个类型是一致时cast()就可以执行具体的转换了。类似的cast()有4个重载版本 251  template class X, class Y 252  inline std::enable_if_t!is_simple_typeY::value, 253                          typename cast_rettyX, const Y::ret_type 254  cast(const Y Val) { 255    assert(isaX(Val) castTy() argument of incompatible type!); 256    return cast_convert_val 257        X, const Y, typename simplify_typeconst Y::SimpleType::doit(Val); 258  } 259  260  template class X, class Y 261  inline typename cast_rettyX, Y::ret_type cast(Y Val) { 262    assert(isaX(Val) castTy() argument of incompatible type!); 263    return cast_convert_valX, Y, 264                            typename simplify_typeY::SimpleType::doit(Val); 265  } 266  267  template class X, class Y 268  inline typename cast_rettyX, Y *::ret_type cast(Y *Val) { 269    assert(isaX(Val) castTy() argument of incompatible type!); 270    return cast_convert_valX, Y*, 271                            typename simplify_typeY*::SimpleType::doit(Val); 272  } 273  274  template class X, class Y 275  inline typename cast_rettyX, std::unique_ptrY::ret_type 276  cast(std::unique_ptrY Val) { 277    assert(isaX(Val.get()) castTy() argument of incompatible type!); 278    using ret_type typename cast_rettyX, std::unique_ptrY::ret_type; 279    return ret_type( 280        cast_convert_valX, Y *, typename simplify_typeY *::SimpleType::doit( 281            Val.release())); 282  } 这里首先由cast_retty::ret_type决定cast()的返回值类型 212  templateclass To, class From 213  struct cast_retty { 214    using ret_type typename cast_retty_wrap 215        To, From, typename simplify_typeFrom::SimpleType::ret_type; 216  }; 其中cast_retty_wrap是这样的定义 198  templateclass To, class From, class SimpleFrom 199  struct cast_retty_wrap { 200    // When the simplified type and the from type are not the same, use the type 201·    // simplifier to reduce the type, then reuse cast_retty_impl to get the 202    // resultant type. 203    using ret_type typename cast_rettyTo, SimpleFrom::ret_type; 204  }; 205  206  templateclass To, class FromTy 207  struct cast_retty_wrapTo, FromTy, FromTy { 208    // When the simplified type is equal to the from type, use it directly. 209    using ret_type typename cast_retty_implTo,FromTy::ret_type; 210  }; 同样第二个版本的cast_retty_wrap是最终调用的版本它使用的cast_retty_impl同样有多个特化版本用户还可以自己定制为了处理常量和指针等情况我们看一下非特化版本 169  templateclass To, class From struct cast_retty_impl { 170    using ret_type To ;       // Normal case, return Ty 171  }; 不出意料cast()的返回值类型就是To类型指针情况下使用引用类型。确定了返回值类型后cast()使用cast_convert_val::doit()执行转换 221  templateclass To, class From, class SimpleFrom struct cast_convert_val { 222    // This is not a simple type, use the template to simplify it... 223    static typename cast_rettyTo, From::ret_type doit(From Val) { 224      return cast_convert_valTo, SimpleFrom, 225        typename simplify_typeSimpleFrom::SimpleType::doit( 226                            simplify_typeFrom::getSimplifiedValue(Val)); 227    } 228  }; 229  230  templateclass To, class FromTy struct cast_convert_valTo,FromTy,FromTy { 231    // This _is_ a simple type, just cast it. 232    static typename cast_rettyTo, FromTy::ret_type doit(const FromTy Val) { 233      typename cast_rettyTo, FromTy::ret_type Res2 234        (typename cast_rettyTo, FromTy::ret_type)const_castFromTy(Val); 235      return Res2; 236    } 237  }; 对于我们最终调用的第二个版本来说所谓的转换就是一个简单的C形式的强制转换不过由于前面的一系列检查这个转换是安全的。 3.2. TrailingObjects 不同于C语言里比较原始的变长类型即union在LLVM里对变长类型有更好的支持。在需要使用变长类型时只需要将llvm::TrailingObjects作为基类。这个类型定义的开头几行是这样的 228  template typename BaseTy, typename... TrailingTys 229  class TrailingObjects : private trailing_objects_internal::TrailingObjectsImpl 230                              trailing_objects_internal::AlignmentCalcHelper 231                                  TrailingTys...::Alignment, 232                              BaseTy, TrailingObjectsBaseTy, TrailingTys..., 233                              BaseTy, TrailingTys... { 234  235    template int A, typename B, typename T, typename P, typename... M 236    friend class trailing_objects_internal::TrailingObjectsImpl; 237  238    template typename... Tys class Foo {}; 239  240    typedef trailing_objects_internal::TrailingObjectsImpl 241        trailing_objects_internal::AlignmentCalcHelperTrailingTys...::Alignment, 242        BaseTy, TrailingObjectsBaseTy, TrailingTys..., BaseTy, TrailingTys... 243        ParentType; 244    using TrailingObjectsBase trailing_objects_internal::TrailingObjectsBase; 245  246    using ParentType::getTrailingObjectsImpl; 这里需要注意232行的TrailingObjectsBaseTy, TrailingTys...这其实是当前TrailingObjects的类型它用途我们会在下面看到。 变长类型对象的大小由totalSizeToAlloc()方法给出在创建对象时它用于确定分配资源的数量。 340    template typename... Tys 341    static constexpr std::enable_if_t 342        std::is_sameFooTrailingTys..., FooTys...::value, size_t 343    totalSizeToAlloc(typename trailing_objects_internal::ExtractSecondType 344                     TrailingTys, size_t::type... Counts) { 345      return sizeof(BaseTy) ParentType::additionalSizeToAllocImpl(0, Counts...); 346    } 在上面243行定义的ParentType类型不出意料有两个特化版本注意ParentType也是当前TrailingObjects的父类。第一个是全特化它是特化产生的派生树的叶子类型模板展开到此结束开始回溯 206  template int Align, typename BaseTy, typename TopTrailingObj, typename PrevTy 207  class TrailingObjectsImplAlign, BaseTy, TopTrailingObj, PrevTy 208      : public TrailingObjectsAlignerAlign { 209  protected: 210    // This is a dummy method, only here so the using doesnt fail -- 211    // it will never be called, because this function recurses backwards 212    // up the inheritance chain to subclasses. 213    static void getTrailingObjectsImpl(); 214  215    static constexpr size_t additionalSizeToAllocImpl(size_t SizeSoFar) { 216      return SizeSoFar; 217    } 218  219    template bool CheckAlignment static void verifyTrailingObjectsAlignment() {} 220  }; 另一个则是偏特化是整个模板展开过程的核心它开头几行是这样的 130  template int Align, typename BaseTy, typename TopTrailingObj, typename PrevTy, 131            typename NextTy, typename... MoreTys 132  class TrailingObjectsImplAlign, BaseTy, TopTrailingObj, PrevTy, NextTy, 133                            MoreTys... 134      : public TrailingObjectsImplAlign, BaseTy, TopTrailingObj, NextTy, 135                                   MoreTys... { 136  137    typedef TrailingObjectsImplAlign, BaseTy, TopTrailingObj, NextTy, MoreTys... 138        ParentType; 139  140    struct RequiresRealignment { 141      static const bool value alignof(PrevTy) alignof(NextTy); 142    }; 143  144    static constexpr bool requiresRealignment() { 145      return RequiresRealignment::value; 146    } 这里需要注意对这两个版本来说与它们相关的类型是模板参数PrevTy。另外BaseTy都是变长类型里的第一个类型。我们关注的additionalSizeToAllocImpl()方法是 193    static constexpr size_t additionalSizeToAllocImpl( 194        size_t SizeSoFar, size_t Count1, 195        typename ExtractSecondTypeMoreTys, size_t::type... MoreCounts) { 196      return ParentType::additionalSizeToAllocImpl( // -- 调用父类的additionalSizeToAllocImpl() 197          (requiresRealignment() ? llvm::alignToalignof(NextTy)(SizeSoFar) 198                                 : SizeSoFar) 199              sizeof(NextTy) * Count1,    // -- 加上我们管的这部分 200          MoreCounts...);               // -- 剩下的交给父类处理 201    } 除了确定对象大小访问指定对象的能力也是不可缺的这由getTrailingObjects()提供它有两个版本一个返回const指针另一个返回非const指针除此之外实现上没有其他区别 297   template typename T T *getTrailingObjects() { 298     verifyTrailingObjectsAssertions(); 299     // Forwards to an impl function with overloads, since member 300     // function templates cant be specialized. 301     return this-getTrailingObjectsImpl( 302         static_castBaseTy *(this), TrailingObjectsBase::OverloadTokenT()); 303   } 上面的方法没有特化版本模板参数T在派生体系里选择最恰当的重载版本。我们以Operation为例 29  class alignas(8) Operation final 29      : public llvm::ilist_node_with_parentOperation, Block, 30        private llvm::TrailingObjectsOperation, BlockOperand, Region, 31                                      detail::OperandStorage { 30 ~ 31行将展开为这样的继承树最底下是叶子节点自底向上继承。与特定TrailingObjectsImpl相关的类型绿色高亮 TrailingObjectsImpl…, Operation , TrailingObjects, Operation, BlockOperand… TrailingObjectsImpl…, Operation , TrailingObjects, BlockOperand, Region… TrailingObjectsImpl…, Operation , TrailingObjects, Region, detail::OperandStorage TrailingObjectsImpl…, Operation , TrailingObjects, detail::OperandStorage 下面的getTrailingObjectsImpl()是由TrailingObjectsImpl定义的。注意返回类型NextTy是模板参数是与当前TrailingObjectsImpl相关类型PrevTy的下一个类型。也就是说下一个对象的位置由前一个对象返回这也是合理的因为只有找到前一个对象才能知道它后面的对象在哪里。 159   static NextTy * 160   getTrailingObjectsImpl(BaseTy *Obj, 161                          TrailingObjectsBase::OverloadTokenNextTy) { 162     auto *Ptr TopTrailingObj::getTrailingObjectsImpl( 163                     Obj, TrailingObjectsBase::OverloadTokenPrevTy()) 164                 TopTrailingObj::callNumTrailingObjects( 165                     Obj, TrailingObjectsBase::OverloadTokenPrevTy()); 166 167     if (requiresRealignment()) 168       return reinterpret_castNextTy *(alignAddr(Ptr, Align::OfNextTy())); 169     else 170       return reinterpret_castNextTy *(Ptr); 171   } 因此这个方法的实现仍然是一个递归的过程在162行的getTrailingObjectsImpl()找出PrevTy类型对象的地址164行的callNumTrailingObjects()返回对象的个数这个方法有两个版本 259   static size_t 260   callNumTrailingObjects(const BaseTy *Obj, 261                          TrailingObjectsBase::OverloadTokenBaseTy) { 262     return 1; 263   } 264 265   template typename T 266   static size_t callNumTrailingObjects(const BaseTy *Obj, 267                                 TrailingObjectsBase::OverloadTokenT) { 268     return Obj-numTrailingObjects(TrailingObjectsBase::OverloadTokenT()); 269   } 第一个版本是缺省实现有多个对象的类型才需要实现第二个版本所需的numTrailingObjects()例如Operation里的BlockOperand与Region。 getTrailingObjectsImpl() 162行的递归也有尽头这个尽头定义在TrailingObjects里 246   static BaseTy * 247   getTrailingObjectsImpl(BaseTy *Obj, 248                      TrailingObjectsBase::OverloadTokenBaseTy) { 249     return Obj; 250   } 这个重载返回了对象的基址即第一个对象的地址。自此回溯回去不断加上每一级的偏移最终得到指定对象的地址。
http://www.yutouwan.com/news/46557/

相关文章:

  • 毕业设计做网站应该学什么网站建设案例收费吗
  • 网站改版的原因易企秀电脑版
  • 优秀网站图标seo网络推广培训班
  • 南县网站开发美度手表网站
  • 给有后台的网站做网页网站专题页是什么
  • 福建建设银行招聘网站深圳优化网站公司哪家好
  • 江苏网站设计谷歌广告平台
  • 网站建设运营的灵魂是什么意思游戏门户网站开发资源
  • 兴义市 网站建设外贸整合营销推广
  • 腾讯云网站建设教学视频邯郸网站设计公司排名
  • 公司网站建设意义网站怎么做微博链接
  • 图片类网站建设网页游戏传奇开服表
  • 帝国做的网站怎么上传网站推广名片
  • 购物商城外贸网站建设深圳设计网站招聘
  • 网站建设实施方案及预算硬件开发流程图
  • 聊城建设网站wordpress手机号登陆不了
  • 整站seo运营北大青鸟教网站开发吗
  • 电商网站开发过程中国建筑工程网施工资料
  • 做航空产品的网站有哪些营销型网站建设课程
  • 有谁帮做网站的太原房产网站建设
  • 企业网站推广的方法包括网站搭建详细步骤
  • 北京网站设计技术乐云seo山西专业网站建设价目
  • 太原建设厅网站建一个网站带管理需要多少钱一年
  • 如何创建二级域名网站产品设计作品
  • 晋江网站建设洛阳网站制作娄底高端网站建设
  • 房产发布网站建设微信首页制作代码
  • 网站建设 6万大连百度关键词排名
  • 阿里云服务器可以做网站吗中关村在线手机论坛
  • 个人网站做交易类的赚钱吗南宁企业建站
  • 自己做网站 什么婚恋网站上认识人 带你做原油交易